windows-nt/Source/XPSP1/NT/admin/wmi/wbem/adapters/odbc/isam.cpp
2020-09-26 16:20:57 +08:00

10795 lines
266 KiB
C++

/***************************************************************************/
/* ISAM.C */
/* Copyright (C) 1995-96 SYWARE Inc., All rights reserved */
/***************************************************************************/
// Commenting #define out - causing compiler error - not sure if needed, compiles
// okay without it.
//#define WINVER 0x0400
#include "precomp.h"
#include "wbemidl.h"
#include <comdef.h>
//smart pointer
_COM_SMARTPTR_TYPEDEF(IWbemServices, IID_IWbemServices);
_COM_SMARTPTR_TYPEDEF(IEnumWbemClassObject, IID_IEnumWbemClassObject);
//_COM_SMARTPTR_TYPEDEF(IWbemContext, IID_IWbemContext );
_COM_SMARTPTR_TYPEDEF(IWbemLocator, IID_IWbemLocator);
_COM_SMARTPTR_TYPEDEF(IWbemClassObject, IID_IWbemClassObject);
_COM_SMARTPTR_TYPEDEF(IWbemQualifierSet, IID_IWbemQualifierSet);
#include "drdbdr.h"
#include "float.h"
#include "resource.h"
#include <comdef.h> //for _bstr_t
#include <vector>
#include "cominit.h" //for Dcom blanket
#include <process.h> //for _beginthreadex
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//Some standard SYNTAX/CIMTYPE qualifier string constants
//#define WBEM_WSYNTAX_CHAR L"CHAR"
//#define WBEM_WSYNTAX_INT8 L"INT8"
#define WBEM_WSYNTAX_UINT8 L"UINT8"
#define WBEM_WSYNTAX_SINT8 L"SINT8"
//#define WBEM_WSYNTAX_UCHAR L"UCHAR"
//#define WBEM_WSYNTAX_BYTE L"BYTE"
//#define WBEM_WSYNTAX_INT64 L"INT64"
#define WBEM_WSYNTAX_SINT64 L"SINT64"
#define WBEM_WSYNTAX_UINT64 L"UINT64"
//#define WBEM_WSYNTAX_INTERVAL L"INTERVAL"
#define WBEM_WSYNTAX_DATETIME L"DATETIME"
//#define WBEM_WSYNTAX_DATE L"DATE"
//#define WBEM_WSYNTAX_TIME L"TIME"
#define WBEM_WSYNTAX_STRING L"STRING"
//#define WBEM_WSYNTAX_DWORD L"DWORD"
//#define WBEM_WSYNTAX_ULONG L"ULONG"
//#define WBEM_WSYNTAX_UINT L"UINT"
#define WBEM_WSYNTAX_SINT32 L"SINT32"
#define WBEM_WSYNTAX_UINT32 L"UINT32"
//#define WBEM_WSYNTAX_LONG L"LONG"
//#define WBEM_WSYNTAX_INT L"INT"
//#define WBEM_WSYNTAX_INTEGER L"INTEGER"
//#define WBEM_WSYNTAX_INT32 L"INT32"
//#define WBEM_WSYNTAX_WCHAR L"WCHAR"
//#define WBEM_WSYNTAX_WCHAR_T L"WCHAR_T"
//#define WBEM_WSYNTAX_INT16 L"INT16"
//#define WBEM_WSYNTAX_SHORT L"SHORT"
#define WBEM_WSYNTAX_SINT16 L"SINT16"
#define WBEM_WSYNTAX_UINT16 L"UINT16"
//#define WBEM_WSYNTAX_USHORT L"USHORT"
//#define WBEM_WSYNTAX_WORD L"WORD"
//#define WBEM_WSYNTAX_CHAR L"CHAR"
#define WBEM_WSYNTAX_STRING_LEN 6
#define WBEM_SYNTAX_STRING "STRING"
#define WBEM_VARIANT_VT_I1 1
#define WBEM_VARIANT_VT_UI1 2
#define WBEM_VARIANT_VT_BSTR 3
#define WBEM_VARIANT_VT_I4 4
#define WBEM_VARIANT_VT_UI4 5
#define WBEM_VARIANT_VT_I2 6
#define WBEM_VARIANT_VT_UI2 7
#define WBEM_VARIANT_VT_R4 8
#define WBEM_VARIANT_VT_R8 9
#define WBEM_VARIANT_VT_I8 10
#define WBEM_VARIANT_VT_UI8 11
#define WBEM_VARIANT_VT_BOOL 12
#define WBEM_VARIANT_VT_ARRAY_I1 13
#define WBEM_VARIANT_VT_ARRAY_UI1 14
#define WBEM_VARIANT_VT_ARRAY_BSTR 15
#define WBEM_VARIANT_VT_ARRAY_I4 16
#define WBEM_VARIANT_VT_ARRAY_UI4 17
#define WBEM_VARIANT_VT_ARRAY_I2 18
#define WBEM_VARIANT_VT_ARRAY_UI2 19
#define WBEM_VARIANT_VT_ARRAY_R4 20
#define WBEM_VARIANT_VT_ARRAY_R8 21
#define WBEM_VARIANT_VT_ARRAY_I8 22
#define WBEM_VARIANT_VT_ARRAY_UI8 23
#define WBEM_VARIANT_VT_ARRAY_BOOL 24
#define WBEM_DSDT_UNKNOWN 0
#define WBEM_DSDT_SINT8 1
#define WBEM_DSDT_UINT8 2
#define WBEM_DSDT_SINT64 3
#define WBEM_DSDT_UINT64 4
//#define WBEM_DSDT_INTERVAL 5
#define WBEM_DSDT_TIMESTAMP 6
//#define WBEM_DSDT_DATE 7
//#define WBEM_DSDT_TIME 8
#define WBEM_DSDT_SMALL_STRING 9
#define WBEM_DSDT_STRING 10
#define WBEM_DSDT_UINT32 11
#define WBEM_DSDT_SINT32 12
#define WBEM_DSDT_SINT16 13
#define WBEM_DSDT_UINT16 14
#define WBEM_DSDT_REAL 15
#define WBEM_DSDT_DOUBLE 16
#define WBEM_DSDT_BIT 17
#define WBEM_DSDT_SINT8_ARRAY 18
#define WBEM_DSDT_UINT8_ARRAY 19
#define WBEM_DSDT_UINT32_ARRAY 20
#define WBEM_DSDT_SINT32_ARRAY 21
#define WBEM_DSDT_BOOL_ARRAY 22
#define WBEM_DSDT_SINT16_ARRAY 23
#define WBEM_DSDT_UINT16_ARRAY 24
#define WBEM_DSDT_REAL_ARRAY 25
#define WBEM_DSDT_DOUBLE_ARRAY 26
#define WBEM_DSDT_SINT64_ARRAY 27
#define WBEM_DSDT_UINT64_ARRAY 28
#define WBEM_DSDT_STRING_ARRAY 29
//#define WBEM_DSDT_INTERVAL_ARRAY 30
#define WBEM_DSDT_TIMESTAMP_ARRAY 31
//#define WBEM_DSDT_DATE_ARRAY 32
//#define WBEM_DSDT_TIME_ARRAY 33
#define WBEM_DSDT_SMALL_STRING_ARRAY 34
BSTR gpPrincipal = NULL;
BOOL g_DebugTracingSwitchedOn = FALSE; //global variable
void __DuhDoSomething(LPCTSTR myStr,...)
{
if (g_DebugTracingSwitchedOn)
{
OutputDebugString(myStr);
//Write data to file
/*
FILE* hfile = fopen("wbemdr32.log", "a");
if (hfile)
{
fwrite(myStr, _mbstrlen(myStr) + 1, _mbstrlen(myStr) + 1, hfile);
fclose(hfile);
}
*/
}
}
//used to create and manage worker thread
CWorkerThreadManager glob_myWorkerThread;
BOOL IsW2KOrMore(void)
{
OSVERSIONINFO os;
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if(!GetVersionEx(&os))
return FALSE; // should never happen
return ( os.dwPlatformId == VER_PLATFORM_WIN32_NT ) && ( os.dwMajorVersion >= 5 ) ;
}
HRESULT WbemSetDynamicCloaking(IUnknown* pProxy,
DWORD dwAuthnLevel, DWORD dwImpLevel)
{
ODBCTRACE("\nWBEM ODBC Driver : WbemSetDynamicCloaking\n");
HRESULT hres;
if(!IsW2KOrMore())
{
// Not NT5 --- don't bother
// ========================
ODBCTRACE("\nWBEM ODBC Driver : WbemSetDynamicCloaking : Not NT5 --- don't bother\n");
return WBEM_S_FALSE;
}
// Try to get IClientSecurity from it
// ==================================
IClientSecurity* pSec;
hres = pProxy->QueryInterface(IID_IClientSecurity, (void**)&pSec);
if(FAILED(hres))
{
// Not a proxy --- not a problem
// =============================
ODBCTRACE("\nWBEM ODBC Driver : WbemSetDynamicCloaking : Not a proxy --- not a problem\n");
return WBEM_S_FALSE;
}
DWORD dwSize = 1000;
char buffer[1001];
buffer[0] = 0;
if ( GetUserName(buffer, &dwSize) )
{
CString lpMessage;
lpMessage.Format("\nUser Account just before SetBlanket is %ld characters long : %s\n", dwSize, buffer);
ODBCTRACE(lpMessage);
}
else
{
ODBCTRACE("\nGetUserName call failed just before SetBlanket\n");
}
hres = pSec->SetBlanket(pProxy,
RPC_C_AUTHN_DEFAULT,//0xa,//RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_DEFAULT,//0,//RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CONNECT,//2,//dwAuthnLevel,
RPC_C_IMP_LEVEL_IMPERSONATE,//3,//dwImpLevel,
NULL,
EOAC_DYNAMIC_CLOAKING//0x20
);
pSec->Release();
if (SUCCEEDED(hres))
{
ODBCTRACE("\nWBEM ODBC Driver : WbemSetDynamicCloaking : SUCCEEDED\n");
}
else
{
ODBCTRACE("\nWBEM ODBC Driver : WbemSetDynamicCloaking : FAILED\n");
}
return hres;
}
HRESULT ISAMSetCloaking1(IUnknown* pProxy, BOOL fIsLocalConnection, BOOL fW2KOrMore, DWORD dwAuthLevel, DWORD dwImpLevel,
BSTR authorityBSTR, BSTR userBSTR, BSTR passwdBSTR, COAUTHIDENTITY ** gpAuthIdentity)
{
HRESULT sc = WBEM_S_FALSE;
if ( fIsLocalConnection && fW2KOrMore )
{
sc = WbemSetDynamicCloaking(pProxy, dwAuthLevel, dwImpLevel);
}
else
{
sc = SetInterfaceSecurityEx(pProxy, authorityBSTR, userBSTR, passwdBSTR,
dwAuthLevel, dwImpLevel, EOAC_NONE, gpAuthIdentity, &gpPrincipal );
}
return sc;
}
HRESULT ISAMSetCloaking2(IUnknown* pProxy, BOOL fIsLocalConnection, BOOL fW2KOrMore, DWORD dwAuthLevel, DWORD dwImpLevel,
COAUTHIDENTITY * gpAuthIdentity)
{
HRESULT sc = WBEM_S_FALSE;
if ( fIsLocalConnection && fW2KOrMore )
{
sc = WbemSetDynamicCloaking(pProxy, dwAuthLevel, dwImpLevel);
}
else
{
SetInterfaceSecurityEx(pProxy, gpAuthIdentity, gpPrincipal, dwAuthLevel, dwImpLevel);
}
return sc;
}
void ISAMCheckWorkingThread_AllocEnv()
{
ODBCTRACE("\nISAMCheckWorkingThread_AllocEnv\n");
//Create working thread if necessary
if (! glob_myWorkerThread.GetThreadHandle() && ! glob_myWorkerThread.IsValid() )
{
ODBCTRACE("\nCreateWorkerThread\n");
glob_myWorkerThread.CreateWorkerThread();
}
else
{
//increament ref count on working thread
MyWorkingThreadParams* m_params = new MyWorkingThreadParams(NULL, NULL, 0, NULL);
//post message to create this object on working thread
CString sMessage;
sMessage.Format( "\nCreateWorkerThread : post message to thread %ld\n", glob_myWorkerThread.GetThreadId() );
ODBCTRACE(sMessage);
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
ResetEvent(m_params->m_EventHnd);
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
BOOL status = PostThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REFCOUNT_INCR, 0, (LPARAM)m_params);
WaitForSingleObject(m_params->m_EventHnd, INFINITE);
ODBCTRACE("\nISAMCheckWorkingThread_AllocEnv : exit\n");
delete m_params;
}
}
void ISAMCheckWorkingThread_FreeEnv()
{
//decrement ref count
MyWorkingThreadParams* m_params = new MyWorkingThreadParams(NULL, NULL, 0, NULL);
//post message to create this object on working thread
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
HANDLE EventHnd = m_params->m_EventHnd;
ResetEvent(EventHnd);
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
BOOL status = PostThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REFCOUNT_DECR, 0, (LPARAM)m_params);
WaitForSingleObject(EventHnd, INFINITE);
delete m_params;
//if zero shut down thread
if ( ! glob_myWorkerThread.GetRefCount() )
{
ISAMCloseWorkerThread1();
//invalidate it
glob_myWorkerThread.Invalidate();
}
}
void ISAMCheckTracingOption()
{
//Read the registry setting to determine if you
//want to enable tracing and set the global variable accordingly
//by default logging is switched off
g_DebugTracingSwitchedOn = FALSE;
HKEY keyHandle = (HKEY)1;
long fStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\WBEM", 0, KEY_READ, &keyHandle);
if (fStatus == ERROR_SUCCESS)
{
DWORD dwLogging;
DWORD sizebuff = sizeof(DWORD);
DWORD typeValue;
fStatus = RegQueryValueEx(keyHandle, "ODBC Logging", NULL,
&typeValue, (LPBYTE)&dwLogging, &sizebuff);
if ( (fStatus == ERROR_SUCCESS) && dwLogging )
{
//switch on logging if 'ODBC Logging' is set to a non-zero number
g_DebugTracingSwitchedOn = TRUE;
}
RegCloseKey(keyHandle);
}
}
void INTFUNC ISAMGetSelectStarList(char** lpWQLSelectStarList, //OUT
TableColumnInfo* pSelectInfo, //IN
LPISAM lpISAM);
void Utility_GetLocaleIDFromString(IN char* lpValue, OUT DWORD& _dwLocale)
{
_bstr_t sFullLocaleStr = lpValue;
if(!_wcsnicmp(sFullLocaleStr, L"MS\\", 3))
{
DWORD dwLocale = 0;
_bstr_t sHexLocaleID = &((wchar_t*)sFullLocaleStr)[3];
swscanf( sHexLocaleID, L"%x", &dwLocale);
// Only set if we have a result
if(dwLocale)
_dwLocale = dwLocale;
}
}
UINT Utility_GetCodePageFromLCID(LCID lcid)
{
char szLocale[12];
UINT cp;
int iNumChars = 0;
iNumChars = GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, szLocale, sizeof(szLocale));
if (iNumChars)
{
szLocale[iNumChars] = '\0';
cp = strtoul(szLocale, NULL, 10);
if (cp)
return cp;
}
return GetACP();
}
void Utility_SetThreadLocale(IN char* lpValue, ULPSETTHREADLOCALE pProcSetThreadLocale)
{
// Default to local system Locale
DWORD dwLocaleID = GetSystemDefaultLCID();
if(lpValue && strlen(lpValue))
{
//Get the locale id from string
Utility_GetLocaleIDFromString(lpValue, dwLocaleID);
}
if (pProcSetThreadLocale)
{
//Now set the thread locale
if((*pProcSetThreadLocale)(dwLocaleID))
{
CString myText;
myText.Format("\nWBEM ODBC Driver : Set ThreadLocaleID OK to: %d\n",dwLocaleID);
ODBCTRACE(myText);
}
else
{
(*pProcSetThreadLocale)(GetSystemDefaultLCID());
CString myText;
myText.Format("\nWBEM ODBC Driver : Set ThreadLocaleID OK to system default: %d\n",GetSystemDefaultLCID());
ODBCTRACE(myText);
}
}
}
int Utility_WideCharToDBCS(IN _bstr_t& _sWCharData,
char** rgbValue,
SDWORD cbValueMax)
{
DWORD dwDBCSBuffLen = cbValueMax;
UINT cpThread = Utility_GetCodePageFromLCID(GetThreadLocale());
// Tried WC_COMPOSITECHECK, didn't seem to work on Japanese machine
int dwDBCSLen = WideCharToMultiByte(cpThread,WC_COMPOSITECHECK, (const wchar_t*)_sWCharData, -1,
*rgbValue, cbValueMax, NULL, NULL);
//The return length included the NULL terminator
//so we need to remove this
if (dwDBCSLen)
--dwDBCSLen;
return dwDBCSLen;
}
void Utility_DBCSToWideChar(IN const char* _dbcsData,
OUT wchar_t** _sOutData, SWORD cbLen)
{
DWORD dwDbcsLen = cbLen ? (cbLen+1) : (_mbstrlen(_dbcsData)+1);
// alloca is much faster (see TN059)
*_sOutData = new wchar_t [dwDbcsLen + 1];
*_sOutData[0] = 0;
UINT cpThread = Utility_GetCodePageFromLCID(GetThreadLocale());
// tried MB_COMPOSITE didn't work on German machine
int dwNumWideChars = MultiByteToWideChar(cpThread, MB_PRECOMPOSED, _dbcsData,
cbLen ? dwDbcsLen : -1,
*_sOutData,dwDbcsLen);
if (!dwNumWideChars)
{
*_sOutData[0] = 0;
}
else
{
if (cbLen)
(*_sOutData)[cbLen] = 0;
}
}
class ThreadLocaleIdManager
{
private:
LCID m_lcid;
HINSTANCE hKernelApi;
ULPSETTHREADLOCALE pProcSetThreadLocale;
public :
ThreadLocaleIdManager(IN LPISAM lpISAM);
ThreadLocaleIdManager(LPUSTR lpLocale);
~ThreadLocaleIdManager();
};
ThreadLocaleIdManager::ThreadLocaleIdManager(IN LPISAM lpISAM)
{
hKernelApi = NULL;
//Save current thread locale id
m_lcid = GetThreadLocale();
pProcSetThreadLocale = NULL;
if (lpISAM->hKernelApi)
{
pProcSetThreadLocale = (ULPSETTHREADLOCALE) GetProcAddress(lpISAM->hKernelApi, "SetThreadLocale");
}
//Change thread locale id
Utility_SetThreadLocale(lpISAM->m_Locale, pProcSetThreadLocale);
}
ThreadLocaleIdManager::ThreadLocaleIdManager(LPUSTR lpLocale)
{
hKernelApi = LoadLibrary("KERNEL32.DLL");
m_lcid = GetThreadLocale();
pProcSetThreadLocale = NULL;
if (hKernelApi)
{
pProcSetThreadLocale = (ULPSETTHREADLOCALE) GetProcAddress(hKernelApi, "SetThreadLocale");
}
//Change thread locale id
Utility_SetThreadLocale((char*)lpLocale, pProcSetThreadLocale);
}
ThreadLocaleIdManager::~ThreadLocaleIdManager()
{
//Restore thread locale id on destruction
if (pProcSetThreadLocale)
{
(*pProcSetThreadLocale)(m_lcid);
}
if (hKernelApi)
{
BOOL status = FreeLibrary(hKernelApi);
if (! status)
{
DWORD err = GetLastError();
CString message ("\n\n***** FreeLibrary KERNEL32 failed : %ld*****\n\n", err);
ODBCTRACE(message);
}
}
}
void ISAMStringConcat(char** resultString, char* myStr)
{
if (myStr)
{
ULONG len = s_lstrlen(myStr);
ULONG oldLen = 0;
if (resultString && *resultString)
oldLen = s_lstrlen(*resultString);
char* buffer = new char [oldLen + len + 1];
buffer[0] = 0;
if (oldLen)
{
sprintf (buffer, "%s%s", *resultString, myStr);
}
else
{
s_lstrcpy(buffer, myStr);
}
//delete old string
if (resultString && *resultString)
delete (*resultString);
//replace with new string
*resultString = buffer;
}
}
ImpersonationManager::ImpersonationManager(char* org_szUser, char* org_szPassword, char* org_szAuthority)
{
ODBCTRACE(_T("\nWBEM ODBC Driver : ImpersonationManager constructor\n"));
hToken = NULL;
hAdvApi = NULL;
// hKernelApi = NULL;
pProcLogonUser = NULL;
pProcImpersonateLoggedOnUser = NULL;
pProcRevertToSelf = NULL;
fImpersonatingNow = FALSE;
//We need to do a LoadLibrary
//as the inpersonation struff is not avaiable on
//Windows 95 and Win32s
fImpersonate = DoInitialChecks();
if ( CanWeImpersonate() )
{
//Extract logon info
ExtractLogonInfo(org_szUser, org_szPassword, org_szAuthority);
}
}
void ImpersonationManager::ExtractLogonInfo(char* org_szUser, char* szPassword, char* szAuthority)
{
//The user name could be the domain and user id
//Make a copy of the username
szUser[0] = 0;
if (org_szUser && strlen(org_szUser))
strncpy(szUser, org_szUser, MAX_USER_NAME_LENGTH);
szUser[MAX_USER_NAME_LENGTH] = 0;
//Find backslash character
char* lpDomain = NULL;
char* lpUser = szUser;
int ch = '\\';
char* backslashPtr = strchr(szUser, ch);
if (backslashPtr)
{
//Found backslash, therefore username
//is domain<blackslash>userid
lpDomain = szUser;
lpUser = backslashPtr + 1;
*backslashPtr = 0; //NULL the backslash so we get two strings
}
else
{
//no domain in user name
//so set domain to authority value
lpDomain = szAuthority;
}
//Call LogonUser via pointer to function
BOOL status = (*pProcLogonUser)( lpUser,
lpDomain,
szPassword,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
&hToken
);
if (!status)
{
status = (*pProcLogonUser)( lpUser,
lpDomain,
szPassword,
LOGON32_LOGON_BATCH,
LOGON32_PROVIDER_DEFAULT,
&hToken
);
}
if (status)
{
ODBCTRACE(_T("\nWBEM ODBC Driver : LogonUser call SUCCEEDED, now impersonating user "));
ODBCTRACE(_T(lpUser));
if (lpDomain && strlen(lpDomain))
{
ODBCTRACE(_T(" on domain "));
ODBCTRACE(_T(lpDomain));
}
ODBCTRACE(_T("\n"));
Impersonate();
}
else
{
ODBCTRACE(_T("\nWBEM ODBC Driver : LogonUser call failed, not doing impersonation for user "));
ODBCTRACE(_T(lpUser));
if (lpDomain && strlen(lpDomain))
{
ODBCTRACE(_T(" on domain "));
ODBCTRACE(_T(lpDomain));
}
ODBCTRACE(_T("\n"));
CString lastErr;
lastErr.Format ("Last Error = %ld \n", GetLastError() );
ODBCTRACE (lastErr);
hToken = NULL;
fImpersonate = FALSE;
}
}
BOOL ImpersonationManager::DoInitialChecks()
{
BOOL fError = FALSE;
//Retieve pointer to functions you want to call
// (only on Windows NT)
hAdvApi = LoadLibrary("ADVAPI32.DLL");
// hKernelApi = LoadLibrary("KERNEL32.DLL");
// if (hAdvApi && hKernelApi)
if (hAdvApi)
{
//LogonUser
pProcLogonUser = (ULPLOGONUSER) GetProcAddress(hAdvApi, "LogonUserA");
//ImpersonateLoggedOnUser
pProcImpersonateLoggedOnUser = (ULPIMPERSONLOGGEDONUSER) GetProcAddress(hAdvApi, "ImpersonateLoggedOnUser");
//RevertToSelf
pProcRevertToSelf = (ULPREVERTTOSELF) GetProcAddress(hAdvApi, "RevertToSelf");
//Check that you have valid pointers to all of these functions
if ( (!pProcLogonUser) || (!pProcImpersonateLoggedOnUser) || (!pProcRevertToSelf) )
{
fError = TRUE;
}
}
else
{
fError = TRUE;
hAdvApi = NULL;
}
if (fError)
{
//Can't load libaries so fail
ODBCTRACE(_T("\nWBEM ODBC Driver : Impersonation libraries/function failier !!!\n"));
if (hAdvApi)
{
FreeLibrary(hAdvApi);
hAdvApi = NULL;
}
// if (hKernelApi)
// {
// FreeLibrary(hKernelApi);
// hKernelApi = NULL;
// }
}
else
{
//success
ODBCTRACE(_T("\nWBEM ODBC Driver : We can do impersonation !!!\n"));
return TRUE;
}
//Default is failure to impersonate
return FALSE;
}
ImpersonationManager::~ImpersonationManager()
{
ODBCTRACE(_T("\nWBEM ODBC Driver : ImpersonationManager DESTRUCTOR\n"));
//If you are doing a SQLDisconnect this class will
//be deleted by something like ISAMClose
//Revert back to original user at this point
//as it won't be done in destructor of MyImpersonator
RevertToYourself();
if (hAdvApi)
{
ODBCTRACE(_T("\nWBEM ODBC Driver : FreeLibrary(hAdvApi)\n"));
FreeLibrary(hAdvApi);
}
// if (hKernelApi)
// {
// FreeLibrary(hKernelApi);
// }
if (hToken)
{
ODBCTRACE(_T("\nWBEM ODBC Driver : CloseHandle(hToken)\n"));
CloseHandle(hToken);
}
}
void ImpersonationManager::Impersonate(char* str)
{
if (fImpersonatingNow)
{
ODBCTRACE("\nWBEM ODBC Driver : ImpersonationManager::Impersonate - already impersonating\n");
}
//Call ImpersonateLoggedOnUser via pointer to function
if ( CanWeImpersonate() && hToken && !fImpersonatingNow )
{
BOOL status = (*pProcImpersonateLoggedOnUser)( hToken );
CString myText(_T("\nWBEM ODBC Driver : "));
//Name of function
if (str)
{
myText += str;
myText += _T(" : ");
}
myText += _T("Impersonating the logged on user ");
//User account you are impersonating
if (szUser)
{
myText += _T("[");
myText += _T(szUser);
myText += _T("]");
}
if (status)
{
myText += _T("\n");
}
else
{
myText += _T(" FAILED\n");
}
ODBCTRACE(myText);
if (status)
fImpersonatingNow = TRUE;
}
}
void ImpersonationManager::RevertToYourself(char* str)
{
//If impersonation is taking place
//revert to original user
//Call RevertToSelf via pointer to function
if ( CanWeImpersonate() && fImpersonatingNow )
{
(*pProcRevertToSelf)();
fImpersonatingNow = FALSE;
CString myText(_T("\nWBEM ODBC Driver : "));
if (str)
{
myText += _T(str);
myText += _T(" : ");
}
myText += _T("Reverting To Self\n");
ODBCTRACE(myText);
}
}
/***********************************************/
MyImpersonator::MyImpersonator(LPDBC myHandle, char* str)
{
hdl = myHandle;
hstmt = NULL;
lpISAM = NULL;
lpImpersonator = NULL;
displayStr = str;
if (hdl->lpISAM && hdl->lpISAM->Impersonate)
{
hdl->lpISAM->Impersonate->Impersonate(displayStr);
}
}
MyImpersonator::MyImpersonator(LPSTMT myHandle, char* str)
{
hdl = NULL;
lpISAM = NULL;
hstmt = myHandle;
displayStr = str;
lpImpersonator = NULL;
if (hstmt->lpdbc && hstmt->lpdbc->lpISAM && hstmt->lpdbc->lpISAM->Impersonate)
{
hstmt->lpdbc->lpISAM->Impersonate->Impersonate(displayStr);
}
}
MyImpersonator::MyImpersonator(LPISAM myHandle, char* str)
{
hdl = NULL;
hstmt = NULL;
lpISAM = myHandle;
displayStr = str;
lpImpersonator = NULL;
if ( !lpISAM )
ODBCTRACE("\nWBEM ODBC Driver : lpISAM is NULL\n");
if (lpISAM && lpISAM->Impersonate)
{
BOOL copyOfFlag = lpISAM->Impersonate->fImpersonatingNow;
lpISAM->Impersonate->fImpersonatingNow = FALSE;
lpISAM->Impersonate->Impersonate(displayStr);
lpISAM->Impersonate->fImpersonatingNow = copyOfFlag;
}
else
{
ODBCTRACE("\nWBEM ODBC Driver : lpISAM->Impersonate is NULL\n");
}
}
MyImpersonator::MyImpersonator(char* szUser, char* szPassword, char* szAuthority, char* str)
{
hdl = NULL;
hstmt = NULL;
lpISAM = NULL;
displayStr = str;
lpImpersonator = new ImpersonationManager(szUser, szPassword, szAuthority);
lpImpersonator->Impersonate(displayStr);
}
MyImpersonator::~MyImpersonator()
{
if (hdl)
{
if (hdl->lpISAM && hdl->lpISAM->Impersonate)
{
hdl->lpISAM->Impersonate->RevertToYourself(displayStr);
}
}
else if (hstmt)
{
if (hstmt->lpdbc && hstmt->lpdbc->lpISAM && hstmt->lpdbc->lpISAM->Impersonate)
{
hstmt->lpdbc->lpISAM->Impersonate->RevertToYourself(displayStr);
}
}
else if (lpISAM)
{
if (lpISAM->Impersonate)
{
BOOL copyOfFlag = lpISAM->Impersonate->fImpersonatingNow;
lpISAM->Impersonate->fImpersonatingNow = TRUE;
lpISAM->Impersonate->RevertToYourself(displayStr);
lpISAM->Impersonate->fImpersonatingNow = copyOfFlag;
}
}
else if (lpImpersonator)
{
//deleting will call RevertToYourself
delete lpImpersonator;
}
}
CBString::CBString(int nSize)
{
m_pString = SysAllocStringLen(NULL, nSize);
m_temp = NULL;
}
CBString::CBString(WCHAR* pwszString, BOOL fInterpretAsBlank)
{
m_temp = NULL;
m_pString = NULL;
if (pwszString)
{
if ( wcslen(pwszString) )
{
m_pString = SysAllocString(pwszString);
}
else
{
//OK, we have a string of zero length
//check if we interpret this as blank or NULL
if (fInterpretAsBlank)
{
m_temp = new wchar_t[1];
m_temp[0] = 0;
m_pString = SysAllocString(m_temp);
}
}
}
}
CBString::~CBString()
{
delete m_temp;
if(m_pString) {
SysFreeString(m_pString);
m_pString = NULL;
}
}
/***************************************************************************/
/* Formats string parameter for output in square braces */
SWORD INTFUNC ISAMFormatCharParm (char* theValue, BOOL &fOutOfBufferSpace,
char* rgbValue, SDWORD cbValueMax, SDWORD FAR* pcbValue,
BOOL fIsBinaryOutput, SDWORD fInt64Check = 0, BOOL fAllElements = TRUE)
{
//Now we must add in string value in the format [string]
//However, if the string contains either [ or ] we must double
//this character in the string sequence
fOutOfBufferSpace = FALSE;
//First store a reference to length of current string
//in case we run out of buffer space when adding this string
SDWORD pcbOldValue = (*pcbValue);
//Do we need to show surrounding braces
//Not for binary output or if we only want to
//show one instance
BOOL fSurroundingBraces = TRUE;
if (fIsBinaryOutput)
fSurroundingBraces = FALSE;
if (!fAllElements)
fSurroundingBraces = FALSE;
//Add leading [ character (not for binary)
if (fSurroundingBraces)
{
if ((1 + (*pcbValue)) <= cbValueMax)
{
rgbValue[(*pcbValue)] = '[';
(*pcbValue) += 1;
}
else
{
fOutOfBufferSpace = TRUE;
}
}
//Add each character in string checking for [ or ] (not for binary)
ULONG cLengthOfElementString = 0;
if (theValue)
cLengthOfElementString = lstrlen(theValue);
if (!fOutOfBufferSpace && cLengthOfElementString)
{
//Copy each character
ULONG cIndex = 0;
while ( (!fOutOfBufferSpace) && theValue[cIndex] )
{
//How much buffer space do we have left
SDWORD cbSpaceLeft = cbValueMax - (*pcbValue);
//???We need to add the character(s) and a NULL terminator
// if ( (fSurroundingBraces) && ((theValue[cIndex] == '[') || (theValue[cIndex] == ']'))
// && (cbSpaceLeft >= 2) )
if ( (fSurroundingBraces) && ((theValue[cIndex] == '[') || (theValue[cIndex] == ']')) )
{
// if (cbSpaceLeft >= 3)
if (cbSpaceLeft >= 2)
{
//Add the character in TWICE
rgbValue[(*pcbValue)] = theValue[cIndex];
rgbValue[(*pcbValue) + 1] = theValue[cIndex];
//rgbValue[(*pcbValue) + 2] = 0;
(*pcbValue) += 2;
}
else
{
fOutOfBufferSpace = TRUE;
}
}
else
{
// if (cbSpaceLeft >= 2)
if (cbSpaceLeft)
{
//Add the character in ONCE
rgbValue[(*pcbValue)] = theValue[cIndex];
//rgbValue[(*pcbValue) + 1] = 0;
(*pcbValue) += 1;
}
else
{
fOutOfBufferSpace = TRUE;
}
}
//Extra check if this is a 64 bit integer
if (fInt64Check == WBEM_DSDT_SINT64)
{
switch (theValue[cIndex])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '+':
case '-':
//OK
break;
default:
{
*pcbValue = 0;
return ERR_INVALID_INTEGER;
}
break;
}
}
if (fInt64Check == WBEM_DSDT_UINT64)
{
switch (theValue[cIndex])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
//OK
break;
default:
{
*pcbValue = 0;
return ERR_INVALID_INTEGER;
}
break;
}
}
cIndex++;
}
}
//Add trailing ] character (not for binary)
if (fSurroundingBraces)
{
if ((!fOutOfBufferSpace) && ((1 + (*pcbValue)) <= cbValueMax))
{
rgbValue[(*pcbValue)] = ']';
(*pcbValue) += 1;
}
else
{
fOutOfBufferSpace = TRUE;
}
}
//If you run out of buffer space indicate to truncate
if (fOutOfBufferSpace)
{
(*pcbValue) = pcbOldValue;
return ISAM_TRUNCATION;
}
return NO_ISAM_ERR;
}
/***************************************************************************/
/* This static function attempts to extract the precision from a property SYNTAX/CIMTYPE string */
/* The SYNTAX/CIMTYPE string will be in the format: */
/* name(precision) [ e.g. STRING(10) ] */
/* The value of 'name' is input as the 1st parameter to this function */
/* The 2nd parameter to this function is the whole SYNTAX/CIMTYPE string */
/* The return value is the precision extracted */
/* If an error occurs 0 is returned */
static LONG GetPrecisionFromSyntaxStr(char* lpHeaderStr, char* lpString)
{
//Check for a valid input strings
if (!lpHeaderStr || !lpString)
return 0;
//Check lengths of strings
LONG cHeaderLen = lstrlen(lpHeaderStr);
LONG cStrLen = lstrlen(lpString);
if ( !cHeaderLen || !cStrLen || (cStrLen < cHeaderLen) )
return 0;
//Set position to expected '('
char* pSearchPos = lpString + cHeaderLen;
char* pNumStart = NULL;
//skip leading white space
while (*pSearchPos && (*pSearchPos == ' '))
{
pSearchPos += 1;
}
if (*pSearchPos != '(')
{
return 0;
}
else
{
//OK, matched the first '(', now continue searching
//until you reach the end of the string or the ')'
pSearchPos += 1;
pNumStart = pSearchPos;
while ( *pSearchPos != ')' )
{
//Check if we have reached end of string before
//finding the ')'. If so return 0
if (*pSearchPos == 0)
return 0;
else
pSearchPos += 1;
}
*pSearchPos = 0;
}
return atoi (pNumStart);
}
/***************************************************************************/
BOOL INTFUNC ISAMGetWbemVariantType(LONG pType, SWORD& wTheVariantType)
{
BOOL fValidType = TRUE;
switch ( pType )
{
case CIM_SINT8: //was VT_I1:
{
wTheVariantType = WBEM_VARIANT_VT_I1;
}
break;
case CIM_UINT8: //was VT_UI1:
{
wTheVariantType = WBEM_VARIANT_VT_UI1;
}
break;
case CIM_SINT16: //was VT_I2:
{
wTheVariantType = WBEM_VARIANT_VT_I2;
}
break;
case CIM_UINT16: //was VT_UI2:
{
wTheVariantType = WBEM_VARIANT_VT_UI2;
}
break;
case CIM_REAL32: //was VT_R4:
{
wTheVariantType = WBEM_VARIANT_VT_R4;
}
break;
case CIM_REAL64: //was VT_R8:
{
wTheVariantType = WBEM_VARIANT_VT_R8;
}
break;
case CIM_BOOLEAN: //was VT_BOOL:
{
wTheVariantType = WBEM_VARIANT_VT_BOOL;
}
break;
case CIM_SINT32: //was VT_I4:
{
wTheVariantType = WBEM_VARIANT_VT_I4;
}
break;
case CIM_UINT32: //was VT_UI4:
{
wTheVariantType = WBEM_VARIANT_VT_UI4;
}
break;
case CIM_SINT64: //was VT_I8:
{
wTheVariantType = WBEM_VARIANT_VT_I8;
}
break;
case CIM_UINT64: //was VT_UI8:
{
wTheVariantType = WBEM_VARIANT_VT_UI8;
}
break;
case CIM_REFERENCE:
case CIM_STRING: //was VT_BSTR
case CIM_DATETIME:
{
wTheVariantType = WBEM_VARIANT_VT_BSTR;
}
break;
default:
{
//Check if it is a CIM_FLAG_ARRAY type
if (pType == (CIM_FLAG_ARRAY | CIM_SINT8))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_I1;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_UINT8))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_UI1;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_SINT32))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_I4;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_UINT32))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_UI4;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_SINT16))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_I2;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_UINT16))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_UI2;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_SINT64))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_I8;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_UINT64))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_UI8;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_REAL32))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_R4;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_REAL64))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_R8;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_BOOLEAN))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_BOOL;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_STRING))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_BSTR;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_REFERENCE))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_BSTR;
}
else if (pType == (CIM_FLAG_ARRAY | CIM_DATETIME))
{
wTheVariantType = WBEM_VARIANT_VT_ARRAY_BSTR;
}
else
{
//unknown type
fValidType = FALSE;
}
}
break;
}
return fValidType;
}
/***************************************************************************/
BOOL INTFUNC ISAMGetDataSourceDependantTypeInfo(SWORD wVariantType, BSTR syntaxStr, SDWORD maxLenVal, SWORD& wDSDT, SWORD& fSqlType, UDWORD& cbPrecision)
{
//Initialize
BOOL fValidType = TRUE;
wDSDT = WBEM_DSDT_UNKNOWN;
switch (wVariantType)
{
case WBEM_VARIANT_VT_I1:
{
fSqlType = SQL_TINYINT;
cbPrecision = UTINYINT_PRECISION;
wDSDT = WBEM_DSDT_SINT8;
}
break;
case WBEM_VARIANT_VT_UI1:
{
fSqlType = SQL_TINYINT;
cbPrecision = UTINYINT_PRECISION;
wDSDT = WBEM_DSDT_UINT8;
}
break;
case WBEM_VARIANT_VT_I2:
{
wDSDT = WBEM_DSDT_SINT16;
fSqlType = SQL_SMALLINT;
cbPrecision = SMALLINT_PRECISION;
}
break;
case WBEM_VARIANT_VT_UI2:
{
wDSDT = WBEM_DSDT_UINT16;
fSqlType = SQL_SMALLINT;
cbPrecision = SMALLINT_PRECISION;
}
break;
case WBEM_VARIANT_VT_I4:
{
wDSDT = WBEM_DSDT_SINT32;
fSqlType = SQL_INTEGER;
cbPrecision = ULONG_PRECISION;
}
break;
case WBEM_VARIANT_VT_UI4:
{
wDSDT = WBEM_DSDT_UINT32;
fSqlType = SQL_INTEGER;
cbPrecision = ULONG_PRECISION;
}
break;
case WBEM_VARIANT_VT_I8:
{
fSqlType = SQL_BIGINT;
cbPrecision = 19;
wDSDT = WBEM_DSDT_SINT64;
}
break;
case WBEM_VARIANT_VT_UI8:
{
fSqlType = SQL_BIGINT;
cbPrecision = 20;
wDSDT = WBEM_DSDT_UINT64;
}
break;
case WBEM_VARIANT_VT_BSTR:
{
if (syntaxStr)
{
if (_wcsnicmp(WBEM_WSYNTAX_STRING, syntaxStr, WBEM_WSYNTAX_STRING_LEN) ==0)
{
LONG cbThePrecision = 254;
//The precision of a string could optionally be stored in
//the MAXLEN qualifier, let us try and get it
if (maxLenVal > 0)
{
cbThePrecision = maxLenVal;
//Double check for *bad* MAXLEN values
if (cbThePrecision == 0)
{
cbThePrecision = 254;
}
}
if (cbThePrecision > 254)
{
fSqlType = SQL_LONGVARCHAR;
//Got precision, so use it
cbPrecision = (cbThePrecision > (long)ISAM_MAX_LONGVARCHAR) ? ISAM_MAX_LONGVARCHAR : cbThePrecision;
wDSDT = WBEM_DSDT_STRING;
}
else
{
fSqlType = SQL_VARCHAR;
if (cbThePrecision)
{
//Got precision, so use it
cbPrecision = cbThePrecision;
}
else
{
//Could not get precision so use default
cbPrecision = 254;
}
wDSDT = WBEM_DSDT_SMALL_STRING;
}
}
else if(_wcsicmp(WBEM_WSYNTAX_DATETIME, syntaxStr) == 0)
{
fSqlType = SQL_TIMESTAMP;
#if TIMESTAMP_SCALE
cbPrecision = 20 + TIMESTAMP_SCALE;
#else
cbPrecision = 19;
#endif
wDSDT = WBEM_DSDT_TIMESTAMP;
}
else
{
//No match, default to SMALL_STRING
fSqlType = SQL_VARCHAR;
cbPrecision = 254;
wDSDT = WBEM_DSDT_SMALL_STRING;
}
}
else
{
//No Syntax string, default to SMALL_STRING
fSqlType = SQL_VARCHAR;
cbPrecision = 254;
wDSDT = WBEM_DSDT_SMALL_STRING;
}
}
break;
case WBEM_VARIANT_VT_R4:
{
fSqlType = SQL_DOUBLE;
cbPrecision = REAL_PRECISION;
wDSDT = WBEM_DSDT_REAL;
}
break;
case WBEM_VARIANT_VT_R8:
{
fSqlType = SQL_DOUBLE;
cbPrecision = DOUBLE_PRECISION;
wDSDT = WBEM_DSDT_DOUBLE; //WBEM_DSDT_REAL;
}
break;
case WBEM_VARIANT_VT_BOOL:
{
fSqlType = SQL_BIT;
cbPrecision = BOOL_PRECISION;
wDSDT = WBEM_DSDT_BIT; //WBEM_DSDT_REAL;
}
break;
case WBEM_VARIANT_VT_ARRAY_I1:
{
fSqlType = SQL_TINYINT;//SQL_LONGVARBINARY;
cbPrecision = 3;//ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_SINT8_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_UI1:
{
fSqlType = SQL_TINYINT; //SQL_LONGVARBINARY;
cbPrecision = 3; //ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_UINT8_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_I2:
{
fSqlType = SQL_SMALLINT; //SQL_LONGVARBINARY;
cbPrecision = 5; //ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_SINT16_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_UI2:
{
fSqlType = SQL_SMALLINT; //SQL_LONGVARBINARY;
cbPrecision = SMALLINT_PRECISION; //ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_UINT16_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_I4:
{
fSqlType = SQL_INTEGER; //SQL_LONGVARBINARY;
cbPrecision = 10; //ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_SINT32_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_UI4:
{
fSqlType = SQL_INTEGER; //SQL_LONGVARBINARY;
cbPrecision = 10; //ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_UINT32_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_I8:
{
fSqlType = SQL_BIGINT; //SQL_LONGVARBINARY;
cbPrecision = 19; //ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_SINT64_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_UI8:
{
fSqlType = SQL_BIGINT; //SQL_LONGVARBINARY;
cbPrecision = 20; //ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_UINT64_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_BOOL:
{
fSqlType = SQL_BIT; //SQL_LONGVARBINARY;
cbPrecision = BOOL_PRECISION; //ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_BOOL_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_R4:
{
fSqlType = SQL_DOUBLE; //SQL_LONGVARBINARY;
cbPrecision = REAL_PRECISION; //ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_REAL_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_R8:
{
fSqlType = SQL_DOUBLE; //SQL_LONGVARBINARY;
cbPrecision = 15; //ISAM_MAX_LONGVARCHAR;
wDSDT = WBEM_DSDT_DOUBLE_ARRAY;
}
break;
case WBEM_VARIANT_VT_ARRAY_BSTR:
{
fSqlType = SQL_VARCHAR; //SQL_LONGVARCHAR; //SQL_LONGVARBINARY;
cbPrecision = 254; //ISAM_MAX_LONGVARCHAR;
if (syntaxStr)
{
if (_wcsnicmp(WBEM_WSYNTAX_STRING, syntaxStr, WBEM_WSYNTAX_STRING_LEN) ==0)
{
LONG cbThePrecision = 254;
//The precision of a string could optionally be stored in
//the MAXLEN qualifier, let us try and get it
if (maxLenVal > 0)
{
cbThePrecision = maxLenVal;
//Double check for *bad* MAXLEN values
if (cbThePrecision == 0)
{
cbThePrecision = 254;
}
}
if (cbThePrecision > 254)
{
fSqlType = SQL_LONGVARCHAR;
//Got precision, so use it
cbPrecision = (cbThePrecision > (long)ISAM_MAX_LONGVARCHAR) ? ISAM_MAX_LONGVARCHAR : cbThePrecision;
wDSDT = WBEM_DSDT_STRING_ARRAY;
}
else
{
fSqlType = SQL_VARCHAR;
if (cbThePrecision)
{
//Got precision, so use it
cbPrecision = cbThePrecision;
}
else
{
//Could not get precision so use default
cbPrecision = 254;
}
wDSDT = WBEM_DSDT_SMALL_STRING_ARRAY;
}
}
else if (_wcsicmp(WBEM_WSYNTAX_DATETIME, syntaxStr) == 0)
{
wDSDT = WBEM_DSDT_TIMESTAMP_ARRAY;
fSqlType = SQL_TIMESTAMP;
#if TIMESTAMP_SCALE
cbPrecision = 20 + TIMESTAMP_SCALE;
#else
cbPrecision = 19;
#endif
}
else
{
//No match, default to SMALL STRING array
wDSDT = WBEM_DSDT_SMALL_STRING_ARRAY;
}
}
else
{
//No Syntax String, default to SMALL STRING array
wDSDT = WBEM_DSDT_SMALL_STRING_ARRAY;
}
}
break;
default:
fValidType = FALSE;
break;
}
//Return indication if this is a valid type
return fValidType;
}
/***************************************************************************/
/* Returns Data-Source Dependent type name in pre-allocated buffer */
void INTFUNC ISAMGetDataSourceDependantTypeStr(SWORD wDSDT, char* lpString)
{
lpString[0] = 0;
switch (wDSDT)
{
case WBEM_DSDT_SINT8:
lstrcpy(lpString, "SINT8");
break;
case WBEM_DSDT_UINT8:
lstrcpy(lpString, "UINT8");
break;
case WBEM_DSDT_SINT64:
lstrcpy(lpString, "SINT64");
break;
case WBEM_DSDT_UINT64:
lstrcpy(lpString, "UINT64");
break;
// case WBEM_DSDT_INTERVAL:
// lstrcpy(lpString, "INTERVAL");
// break;
case WBEM_DSDT_TIMESTAMP:
lstrcpy(lpString, "TIMESTAMP");
break;
// case WBEM_DSDT_DATE:
// lstrcpy(lpString, "DATE");
// break;
// case WBEM_DSDT_TIME:
// lstrcpy(lpString, "TIME");
// break;
case WBEM_DSDT_SMALL_STRING:
lstrcpy(lpString, "SMALL_STRING");
break;
case WBEM_DSDT_STRING:
lstrcpy(lpString, "STRING");
break;
case WBEM_DSDT_UINT32:
lstrcpy(lpString, "UINT32");
break;
case WBEM_DSDT_SINT32:
lstrcpy(lpString, "SINT32");
break;
case WBEM_DSDT_SINT16:
lstrcpy(lpString, "SINT16");
break;
case WBEM_DSDT_UINT16:
lstrcpy(lpString, "UINT16");
break;
case WBEM_DSDT_REAL:
lstrcpy(lpString, "REAL");
break;
case WBEM_DSDT_DOUBLE:
lstrcpy(lpString, "DOUBLE");
break;
case WBEM_DSDT_BIT:
lstrcpy(lpString, "BIT");
break;
case WBEM_DSDT_SINT8_ARRAY:
lstrcpy(lpString, "SINT8_ARRAY");
break;
case WBEM_DSDT_UINT8_ARRAY:
lstrcpy(lpString, "UINT8_ARRAY");
break;
case WBEM_DSDT_UINT32_ARRAY:
lstrcpy(lpString, "UINT32_ARRAY");
break;
case WBEM_DSDT_SINT32_ARRAY:
lstrcpy(lpString, "SINT32_ARRAY");
break;
case WBEM_DSDT_BOOL_ARRAY:
lstrcpy(lpString, "BOOL_ARRAY");
break;
case WBEM_DSDT_SINT16_ARRAY:
lstrcpy(lpString, "SINT16_ARRAY");
break;
case WBEM_DSDT_UINT16_ARRAY:
lstrcpy(lpString, "UINT16_ARRAY");
break;
case WBEM_DSDT_REAL_ARRAY:
lstrcpy(lpString, "REAL_ARRAY");
break;
case WBEM_DSDT_DOUBLE_ARRAY:
lstrcpy(lpString, "DOUBLE_ARRAY");
break;
case WBEM_DSDT_SINT64_ARRAY:
lstrcpy(lpString, "SINT64_ARRAY");
break;
case WBEM_DSDT_UINT64_ARRAY:
lstrcpy(lpString, "UINT64_ARRAY");
break;
case WBEM_DSDT_STRING_ARRAY:
lstrcpy(lpString, "STRING_ARRAY");
break;
case WBEM_DSDT_SMALL_STRING_ARRAY:
lstrcpy(lpString, "SMALL_STRING_ARRAY");
break;
// case WBEM_DSDT_INTERVAL_ARRAY:
// lstrcpy(lpString, "INTERVAL_ARRAY");
// break;
case WBEM_DSDT_TIMESTAMP_ARRAY:
lstrcpy(lpString, "TIMESTAMP_ARRAY");
break;
// case WBEM_DSDT_DATE_ARRAY:
// lstrcpy(lpString, "DATE_ARRAY");
// break;
// case WBEM_DSDT_TIME_ARRAY:
// lstrcpy(lpString, "TIME_ARRAY");
// break;
default:
break;
}
}
/***************************************************************************/
/***************************************************************************/
/***************************************************************************/
//
// Methods for ClassColumnInfo
//
/***************************************************************************/
/* ClassColumnInfo constructor */
/* */
/* Parameter pType is the Variant type of the property */ //
/* Parameter pSYNTAX contains NULL or the SYNTAX string for the property */
/* Parameter fGotSyntax indicates if a SYNTAX string is present */
/* This class is only used internaly by ClassColumnInfoBase and provides */
/* extracts property attribute values, like type, precision, scale */
ClassColumnInfo :: ClassColumnInfo(LONG pType, VARIANT* pSYNTAX, SDWORD maxLenVal, BOOL fGotSyntax, BOOL fIsLazy)
{
//Initialize
VariantInit(&aVariantSYNTAX);
szTypeName[0] = 0;
fValidType = TRUE;
varType = pType;
SWORD wDSDT = WBEM_DSDT_UNKNOWN;
SWORD wTheVariantType = 0;
ibScale = 0;
fIsLazyProperty = fIsLazy;
//Make a copy of input variants
if (fGotSyntax)
VariantCopy(&aVariantSYNTAX, pSYNTAX);
//Now work out info
// Get the column Type, Precision, Scale etc...
//You may need to get info from both column value
//and SYNTAX attributes in order to map column type to SQL_* type
//You may be able to directly map variant type to SQL_* type
//however, for some variant types there may be multiple mappings
//and so the SYNTAX attribute needs to be fetched in order to
//complete the mapping to SQL_* type.
fValidType = ISAMGetWbemVariantType(pType, wTheVariantType);
if (fValidType)
{
fValidType = ISAMGetDataSourceDependantTypeInfo
(wTheVariantType,
(fGotSyntax && aVariantSYNTAX.bstrVal) ? aVariantSYNTAX.bstrVal : NULL,
maxLenVal,
wDSDT, fSqlType, cbPrecision);
if (fValidType)
ISAMGetDataSourceDependantTypeStr(wDSDT, (char*)szTypeName);
}
}
/***************************************************************************/
/* Destructor */
ClassColumnInfo :: ~ClassColumnInfo()
{
//Tidy up
VariantClear(&aVariantSYNTAX);
}
/***************************************************************************/
//
// Methods of Class ClassColumnInfoBase
//
/***************************************************************************/
/***************************************************************************/
/***************************************************************************/
/* ClassColumnInfoBase Constructor */
/* */
/* This class is used as a repository */
/* to extract information about a */
/* property */
ClassColumnInfoBase :: ClassColumnInfoBase(LPISAMTABLEDEF pOrgTableDef, BOOL fIs__Gen)
{
//Initialize
isValid = TRUE;
pTableDef = pOrgTableDef;
pColumnInformation = NULL;
iColumnNumber = 0;
fIs__Generic = fIs__Gen;
cSystemProperties = 0;
embedded = NULL;
embeddedSize = 0;
//We need to get column information for a column
//The information we need is stored in a VALUE variant and the property attribute "SYNTAX"
//To get the property attribute "SYNTAX" variant we need the property/column name
//Get the column/property name
//We do this by getting the list of all property names in a SAFEARRAY
//create SAFEARRAY to store BSTR's
rgSafeArray = NULL;
//Check for pass-through SQL
if ( ! (pTableDef->pSingleTable) )
{
isValid = FALSE;
return;
}
//Get the names of all the properties/columns
SCODE scT = pTableDef->pSingleTable->GetNames ( NULL, 0, NULL, &rgSafeArray );
if (FAILED(scT))
{
rgSafeArray = NULL;
isValid = FALSE;
}
else
{
SafeArrayLock(rgSafeArray);
}
//Work out number of properties/columns
SafeArrayGetLBound(rgSafeArray, 1, &iLBound );
SafeArrayGetUBound(rgSafeArray, 1, &iUBound );
cColumnDefs = (UWORD) (iUBound - iLBound + 1);
if (fIs__Generic)
{
//This class is the prototype class for
//a passthrough SQL result set
//calculate additional embedded proprties
Get__GenericProfile();
}
}
/***************************************************************************/
/* Destructor */
ClassColumnInfoBase :: ~ClassColumnInfoBase()
{
//Tidy Up
if (rgSafeArray)
{
SafeArrayUnlock(rgSafeArray);
SafeArrayDestroy(rgSafeArray);
}
if (pColumnInformation)
delete pColumnInformation;
//SAI ADDED if (cSystemProperties)
{
if (embedded)
{
for (UWORD i = 0; i < embeddedSize; i++)
{
if (embedded[i])
{
delete embedded[i];
embedded[i] = NULL;
}
}
delete embedded;
embedded = NULL;
}
}
}
/***************************************************************************/
/* Sets up extra column information for the selected */
/* column if required */
BOOL ClassColumnInfoBase :: Setup(LONG iColumnNum)
{
//Sets up extra column information of specified column
if ( (!pColumnInformation) || (iColumnNumber != iColumnNum) )
{
//Wrong column info, delete old column info
//and create for new column
if (pColumnInformation)
{
delete pColumnInformation;
pColumnInformation = NULL;
}
//Setup column info
if ( FAILED(GetColumnInfo(iColumnNum)) )
{
return FALSE;
}
else
{
//Check the newly created column information
if (! pColumnInformation->IsValidInfo() )
return FALSE;
iColumnNumber = iColumnNum;
}
}
return TRUE;
}
/***************************************************************************/
BOOL ClassColumnInfoBase :: GetVariantType(LONG iColumnNum, LONG &lVariant)
{
if ( !Setup(iColumnNum) )
return FALSE;
lVariant = pColumnInformation->GetVariantType();
return TRUE;
}
/***************************************************************************/
BOOL ClassColumnInfoBase :: GetSQLType(LONG iColumnNum, SWORD &wSQLType)
{
if ( !Setup(iColumnNum) )
return FALSE;
wSQLType = pColumnInformation->GetSQLType();
return TRUE;
}
/***************************************************************************/
BOOL ClassColumnInfoBase :: GetTypeName(LONG iColumnNum, UCHAR* &pbTypeName)
{
if ( !Setup(iColumnNum) )
return FALSE;
pbTypeName = pColumnInformation->GetTypeName();
return TRUE;
}
/***************************************************************************/
BOOL ClassColumnInfoBase :: GetPrecision(LONG iColumnNum, UDWORD &uwPrecision)
{
if ( !Setup(iColumnNum) )
return FALSE;
uwPrecision = pColumnInformation->GetPrecision();
return TRUE;
}
/***************************************************************************/
BOOL ClassColumnInfoBase :: GetScale(LONG iColumnNum, SWORD &wScale)
{
if ( !Setup(iColumnNum) )
return FALSE;
wScale = pColumnInformation->GetScale();
return TRUE;
}
/***************************************************************************/
BOOL ClassColumnInfoBase :: IsNullable(LONG iColumnNum, SWORD &wNullable)
{
if ( !Setup(iColumnNum) )
return FALSE;
wNullable = pColumnInformation->IsNullable();
return TRUE;
}
/***************************************************************************/
BOOL ClassColumnInfoBase :: IsLazy(LONG iColumnNum, BOOL &fLazy)
{
if ( !Setup(iColumnNum) )
return FALSE;
fLazy = pColumnInformation->IsLazy();
return TRUE;
}
/***************************************************************************/
BOOL ClassColumnInfoBase :: GetDataTypeInfo(LONG iColumnNum, LPSQLTYPE &pSQLType)
{
if ( !Setup(iColumnNum) )
return FALSE;
pSQLType = pColumnInformation->GetDataTypeInfo();
return TRUE;
}
/***************************************************************************/
SWORD ClassColumnInfoBase :: GetColumnName(LONG iColumnNumber, LPSTR pColumnName, LPSTR pColumnAlias)
{
//Create a store for column name
BSTR lpbString;
//Now we want column number "iColumnNumber"
CBString myString;
if (fIs__Generic)
{
CBString myAlias;
GetClassObject(iColumnNumber, myString, myAlias);
lpbString = myString.GetString();
//Copy across alias
if (pColumnAlias)
{
pColumnAlias[0] = 0;
//RAID 42256
char* pTemp = (char*) pColumnAlias;
_bstr_t myValue((BSTR)myAlias.GetString());
Utility_WideCharToDBCS(myValue, &pTemp, MAX_COLUMN_NAME_LENGTH);
pColumnAlias[MAX_COLUMN_NAME_LENGTH] = 0;
}
}
else
{
if ( FAILED(SafeArrayGetElement(rgSafeArray, &iColumnNumber, &lpbString)) )
{
return SQL_ERROR;
}
}
//copy column name
pColumnName[0] = 0;
//RAID 42256
char* pTemp = (char*) pColumnName;
_bstr_t myValue((BSTR)lpbString);
Utility_WideCharToDBCS(myValue, &pTemp, MAX_COLUMN_NAME_LENGTH);
pColumnName[MAX_COLUMN_NAME_LENGTH] = 0;
//SAI ADDED
if (!fIs__Generic)
SysFreeString(lpbString);
return SQL_SUCCESS;
}
/***************************************************************************/
// Checked for SetInterfaceSecurityEx on IWbemServices
UWORD ClassColumnInfoBase ::Get__GenericProfile()
{
UWORD propertyCount = cColumnDefs;
SAFEARRAY FAR* rgSafeArrayExtra = NULL;
//Get the names of the non-system properties/columns
SCODE scT = pTableDef->pSingleTable->GetNames ( NULL, WBEM_FLAG_NONSYSTEM_ONLY, NULL, &rgSafeArrayExtra );
if (FAILED(scT))
{
rgSafeArrayExtra = NULL;
return cColumnDefs;
}
//Lower bound
LONG iLBoundExtra;
//Upper bound
LONG iUBoundExtra;
SafeArrayGetLBound(rgSafeArrayExtra, 1, &iLBoundExtra );
SafeArrayGetUBound(rgSafeArrayExtra, 1, &iUBoundExtra );
UWORD cNumColumnDefs = (UWORD) (iUBoundExtra - iLBoundExtra + 1);
//As we know the total number of properties (cColumnDefs)
//and the total number of non-system properties (cNumColumnDefs)
//we can calculate the number of system properties
cSystemProperties = cColumnDefs - cNumColumnDefs;
embedded = new CEmbeddedDataItems* [cNumColumnDefs];
embeddedSize = cNumColumnDefs;
for (long i = 0; i < embeddedSize; i++)
{
embedded[i] = new CEmbeddedDataItems();
}
//Update number of columns (from ISAMTableDef)
if (pTableDef && pTableDef->passthroughMap)
{
cColumnDefs = (UWORD) pTableDef->passthroughMap->GetCount();
}
for (i = 0; i < cNumColumnDefs; i++)
{
//Create a store for column name
BSTR lpbString;
//Now we want column number "i"
if ( FAILED(SafeArrayGetElement(rgSafeArrayExtra, &i, &lpbString)) )
{
return cColumnDefs;
}
//Get the property type and value
CIMTYPE vType;
VARIANT pVal;
if ( FAILED(pTableDef->pSingleTable->Get(lpbString, 0, &pVal, &vType, 0)) )
{
return cColumnDefs;
}
//We are looking for embedded objects
if (vType == CIM_OBJECT)
{
(embedded[i])->embeddedName = lpbString;
IWbemClassObject* myEmbeddedObj = NULL;
IUnknown* myUnk = pVal.punkVal;
//(5)
myUnk->QueryInterface(IID_IWbemClassObject, (void**)&myEmbeddedObj);
if (myEmbeddedObj)
{
//Get the __CLASS property
//Get the property type and value
VARIANT pVal2;
CBString cimClass(L"__CLASS", FALSE);
if ( SUCCEEDED(myEmbeddedObj->Get(cimClass.GetString(), 0, &pVal2, NULL, 0)) )
{
_bstr_t wEmbeddedClassName = pVal2.bstrVal;
(embedded[i])->cClassObject = NULL;
IWbemServicesPtr myServicesPtr = NULL;
ISAMGetIWbemServices(pTableDef->lpISAM, *(pTableDef->pGateway2), myServicesPtr);
myServicesPtr->GetObject(wEmbeddedClassName, 0, pTableDef->pContext, &((embedded[i])->cClassObject), NULL);
VariantClear(&pVal2);
}
myEmbeddedObj->Release();
}
VariantClear(&pVal);
}
SysFreeString(lpbString);
}
//Tidy Up
SafeArrayDestroy(rgSafeArrayExtra);
return propertyCount;
}
/***************************************************************************/
IWbemClassObject* ClassColumnInfoBase :: GetClassObject(LONG iColumnNumber, CBString& lpPropName, CBString& cbTableAlias)
{
//Examine the zero-based column number and return the
//parent class object containing the requested property
if (pTableDef->passthroughMap)
{
PassthroughLookupTable* passthroughElement = NULL;
WORD myIndex = (WORD)iColumnNumber;
BOOL status = pTableDef->passthroughMap->Lookup(myIndex, (void*&)passthroughElement);
if (status)
{
lpPropName.AddString(passthroughElement->GetColumnName(), FALSE);
char* lpTableAlias = passthroughElement->GetTableAlias();
if (!lpTableAlias || !strlen(lpTableAlias))
return NULL;
cbTableAlias.AddString(lpTableAlias, FALSE);
//Now get the class object
UWORD cNumColumnDefs = cColumnDefs; //(as this value has been updated)
UWORD index = 0;
while (index < cNumColumnDefs)
{
if ((embedded[index])->embeddedName.GetString())
{
if (_wcsicmp((embedded[index])->embeddedName.GetString(), cbTableAlias.GetString()) == 0)
{
//found embedded object
return ((embedded[index])->cClassObject);
}
}
index++;
}
}
}
//should not reach here
return NULL;
}
/***************************************************************************/
SWORD ClassColumnInfoBase :: GetColumnInfo(LONG iColumnNumber)
{
//Create a store for column name
BSTR lpbString;
IWbemClassObjectPtr parentClass = NULL;
CBString myString;
if (fIs__Generic)
{
CBString myAlias; //not used
parentClass = GetClassObject(iColumnNumber, myString, myAlias);
lpbString = myString.GetString();
}
else
{
parentClass = pTableDef->pSingleTable;
//Now we want column number "iColumnNumber"
if ( FAILED(SafeArrayGetElement(rgSafeArray, &iColumnNumber, &lpbString)) )
{
return SQL_ERROR;
}
}
#ifdef TESTING
//copy column name
char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
pColumnName[0] = 0;
wcstombs(pColumnName, lpbString, MAX_COLUMN_NAME_LENGTH);
pColumnName[MAX_COLUMN_NAME_LENGTH] = 0;
#endif
//Get the "Type" value
CIMTYPE pColumnType;
if ( FAILED(parentClass->Get(lpbString, 0, NULL, &pColumnType, 0)) )
{
if (!fIs__Generic)
SysFreeString(lpbString);
return SQL_ERROR;
}
//flag to indicate if property is marked 'lazy'
BOOL fIsLazyProperty = FALSE;
//Now get the qualifiers (if available)
IWbemQualifierSetPtr pQualifierSet = NULL;
if ( S_OK != (parentClass->GetPropertyQualifierSet
(lpbString, &pQualifierSet)) )
{
if (!fIs__Generic)
SysFreeString(lpbString);
//No qualifers, therefore no CIMTYPE, MAX & LAZY qualifiers
pColumnInformation = new ClassColumnInfo(pColumnType, NULL, NULL, FALSE, fIsLazyProperty);
return SQL_SUCCESS;
}
//Get the lazy qualifer (if applicable)
VARIANT pValLazy;
BSTR lazyStr = SysAllocString(WBEMDR32_L_LAZY);
if ( S_OK == (pQualifierSet->Get(lazyStr, 0, &pValLazy, NULL)) )
{
fIsLazyProperty = TRUE;
VariantClear(&pValLazy);
}
else
{
fIsLazyProperty = FALSE;
}
SysFreeString(lazyStr);
VARIANT pVal;
//Get the CIMTYPE qualifier
BSTR cimTypeStr = SysAllocString(WBEMDR32_L_CIMTYPE);
if ( S_OK != (pQualifierSet->Get(cimTypeStr, 0, &pVal, NULL)) )
{
//No CIMTYPE qualifier (therefore no max string)
pColumnInformation = new ClassColumnInfo(pColumnType, NULL,//&pVal
NULL, FALSE, fIsLazyProperty);
}
else
{
//Got the CIMTYPE qualifier
//Now get the optional MAX qualifier
long cbMaxValue = 0;
VARIANT pVal2;
BSTR maxStr = SysAllocString(WBEMDR32_L_MAX);
if ( S_OK != (pQualifierSet->Get(maxStr, 0, &pVal2, NULL)) )
{
//Got CIMTYPE but no MAX qualifier
pColumnInformation = new ClassColumnInfo(pColumnType, &pVal, NULL, TRUE, fIsLazyProperty);
}
else
{
//Got CIMTYPE and got MAX qualifier
SDWORD maxLenVal = pVal2.iVal;
pColumnInformation = new ClassColumnInfo(pColumnType, &pVal, maxLenVal, TRUE, fIsLazyProperty);
VariantClear(&pVal2);
}
SysFreeString(maxStr);
VariantClear(&pVal);
}
SysFreeString(cimTypeStr);
if (!fIs__Generic)
SysFreeString(lpbString);
return SQL_SUCCESS;
}
/***************************************************************************/
SWORD ClassColumnInfoBase :: GetKey(LONG iColumnNumber, BOOL &isAKey)
{
//We return FALSE for now as we don't support SQLPrimaryKeys
//If we do implement SQLPrimaryKeys we can comment out the next two lines
isAKey = FALSE;
return SQL_SUCCESS;
//Create a store for column name
BSTR lpbString;
//Now we want column number "iColumnNumber"
if ( FAILED(SafeArrayGetElement(rgSafeArray, &iColumnNumber, &lpbString)) )
{
return SQL_ERROR;
}
//Now get the Key attribute value (if available)
IWbemQualifierSetPtr pQualifierSet = NULL;
if ( S_OK != (pTableDef->pSingleTable->GetPropertyQualifierSet
(lpbString, &pQualifierSet)) )
{
SysFreeString(lpbString);
return SQL_ERROR;
}
//SAI ADDED - Tidy up
SysFreeString(lpbString);
lpbString = NULL;
//Now get the KEY attribute value (if available)
VARIANT pVal;
isAKey = FALSE;
BSTR keyBSTR = SysAllocString(WBEMDR32_L_KEY);
if ( S_OK == (pQualifierSet->Get(keyBSTR, 0, &pVal, NULL)) )
{
isAKey = (pVal.boolVal != 0) ? TRUE : FALSE;
//TidyUp
VariantClear(&pVal);
}
SysFreeString(keyBSTR);
return SQL_SUCCESS;
}
/***************************************************************************/
SWORD ClassColumnInfoBase :: GetColumnAttr(LONG iColumnNumber, LPSTR pAttrStr, SDWORD cbValueMax, SDWORD &cbBytesCopied)
{
SWORD err = SQL_SUCCESS;
cbBytesCopied = 0;
//Create a store for column name
BSTR lpbString;
//Now we want column number "iColumnNumber"
if ( FAILED(SafeArrayGetElement(rgSafeArray, &iColumnNumber, &lpbString)) )
{
return SQL_ERROR;
}
#ifdef TESTING
//copy column name
char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
pColumnName[0] = 0;
wcstombs(pColumnName, lpbString, MAX_COLUMN_NAME_LENGTH);
pColumnName[MAX_COLUMN_NAME_LENGTH] = 0;
#endif
//Get attributes for chosen column
IWbemQualifierSetPtr pQualifierSet = NULL;
if ( S_OK != (pTableDef->pSingleTable->GetPropertyQualifierSet(lpbString, &pQualifierSet)) )
{
SysFreeString(lpbString);
return SQL_ERROR;
}
SysFreeString(lpbString);
lpbString = NULL;
//Get CIMTYPE String
VARIANT pVal2;
BSTR syntaxStr = NULL;
BOOL fClearpVal2 = FALSE;
BSTR cimTypeBSTR = SysAllocString(WBEMDR32_L_CIMTYPE);
if ( S_OK == (pQualifierSet->Get(cimTypeBSTR, 0, &pVal2, NULL)) )
{
if (pVal2.bstrVal)
syntaxStr = pVal2.bstrVal;
fClearpVal2 = TRUE;
}
SysFreeString(cimTypeBSTR);
//Get the MAX String
VARIANT pVal3;
SDWORD maxLenVal = 0;
BOOL fClearpVal3 = FALSE;
BSTR maxBSTR = SysAllocString(WBEMDR32_L_MAX);
if ( S_OK == (pQualifierSet->Get(maxBSTR, 0, &pVal3, NULL)) )
{
maxLenVal = pVal3.iVal;
fClearpVal3 = TRUE;
}
SysFreeString(maxBSTR);
//Now get list of attribute names from attribute set
//create SAFEARRAY to store attribute names
SAFEARRAY FAR* rgNames = NULL;
//Fetch attribute names
pQualifierSet->GetNames(0, &rgNames);
SafeArrayLock(rgNames);
//Get the upper and lower bounds of SAFEARRAY
long lowerBound;
SafeArrayGetLBound(rgNames, 1, &lowerBound);
long upperBound;
SafeArrayGetUBound(rgNames, 1, &upperBound);
//Get each name out
BSTR pTheAttrName;
for (long ix = lowerBound; ix <= upperBound; ix++)
{
if ( SUCCEEDED(SafeArrayGetElement(rgNames, &ix, &pTheAttrName)) )
{
//Get variant value of named attribute
VARIANT pVal;
if ( S_OK == (pQualifierSet->Get(pTheAttrName, 0, &pVal, NULL)) )
{
//Decode variant value, as we do not know actual size of value
//beforehand we will create buffers in increments of 200 bytes
//until we can get the value with truncation
ULONG cwAttemptToGetValue = 0;
ULONG wBufferLen = 0;
char* buffer = NULL;
SDWORD cbValue;
SWORD err = ISAM_TRUNCATION;
while ( err == ISAM_TRUNCATION )
{
if (buffer)
delete buffer;
wBufferLen = 200 * (++cwAttemptToGetValue);
buffer = new char [wBufferLen + 1];
buffer[0] = 0;
err = ISAMGetValueFromVariant(pVal, SQL_C_CHAR, buffer, wBufferLen, &cbValue, 0, syntaxStr, maxLenVal);
}
VariantClear (&pVal);
if (fClearpVal2)
VariantClear (&pVal2);
if (fClearpVal3)
VariantClear (&pVal3);
//Check for error
if (err != NO_ISAM_ERR)
{
pTableDef->lpISAM->errcode = err;
SafeArrayUnlock(rgNames);
SafeArrayDestroy(rgNames);
SysFreeString(pTheAttrName);
delete buffer;
return SQL_ERROR;
}
//Once we have the name and value of the attribute let us try and add
//it to the output buffer
//First try and save the attribute name
//Save old number of bytes copied so that if truncation
//occurs we can roll back to original state
SDWORD pdbOldValue = cbBytesCopied;
//If this is not the first attribute in the list
//we must separate the attribute/value pairs with "\n" character
if ( (cbValueMax - cbBytesCopied) && cbBytesCopied)
{
pAttrStr[cbBytesCopied++] = '\n';
}
//Now add in attribute name
//first convert it from a BSTR to a char*
char* lpTheAttrString = NULL;
ULONG cLength = 0;
if (pTheAttrName)
{
cLength = wcslen(pTheAttrName);
lpTheAttrString = new char [cLength + 1];
lpTheAttrString[0] = 0;
wcstombs(lpTheAttrString, pTheAttrName, cLength);
lpTheAttrString[cLength] = 0;
}
BOOL fOutOfBufferSpace = FALSE;
err = ISAMFormatCharParm (lpTheAttrString, fOutOfBufferSpace,
pAttrStr, cbValueMax, &cbBytesCopied, FALSE);
delete lpTheAttrString;
//Now add in value
if (err == NO_ISAM_ERR)
{
err = ISAMFormatCharParm (buffer, fOutOfBufferSpace,
pAttrStr, cbValueMax, &cbBytesCopied, FALSE);
}
delete buffer;
buffer = NULL;
if (err != NO_ISAM_ERR)
{
//Truncation took place so rollback
cbBytesCopied = pdbOldValue;
//Null terminate
pAttrStr[cbBytesCopied] = 0;
SafeArrayUnlock(rgNames);
SafeArrayDestroy(rgNames);
SysFreeString(pTheAttrName);
return SQL_SUCCESS_WITH_INFO;
}
//Null terminate
pAttrStr[cbBytesCopied] = 0;
}
else
{
//Error, tidy up and then quit
SysFreeString(pTheAttrName);
SafeArrayUnlock(rgNames);
SafeArrayDestroy(rgNames);
return SQL_ERROR;
}
SysFreeString(pTheAttrName);
}
else
{
//Error, tidy up and then quit
SafeArrayUnlock(rgNames);
SafeArrayDestroy(rgNames);
return SQL_ERROR;
}
}
//Tidy Up
SafeArrayUnlock(rgNames);
SafeArrayDestroy(rgNames);
return SQL_SUCCESS;
}
/***************************************************************************/
SWORD INTFUNC ISAMGetTableAttr(LPISAMTABLEDEF lpISAMTableDef, LPSTR pAttrStr, SDWORD cbValueMax, SDWORD &cbBytesCopied)
{
SWORD err = SQL_SUCCESS;
cbBytesCopied = 0;
//Get attributes for chosen table
IWbemQualifierSetPtr pQualifierSet = NULL;
if ( S_OK != (lpISAMTableDef->pSingleTable->GetQualifierSet(&pQualifierSet)) )
{
return SQL_ERROR;
}
//Now get list of attribute names from attribute set
//create SAFEARRAY to store attribute names
SAFEARRAY FAR* rgNames = NULL;
//Fetch attribute names
pQualifierSet->GetNames(0, &rgNames);
SafeArrayLock(rgNames);
//Get the upper and lower bounds of SAFEARRAY
long lowerBound;
SafeArrayGetLBound(rgNames, 1, &lowerBound);
long upperBound;
SafeArrayGetUBound(rgNames, 1, &upperBound);
//Get each name out
BSTR pTheAttrName;
for (long ix = lowerBound; ix <= upperBound; ix++)
{
if ( SUCCEEDED(SafeArrayGetElement(rgNames, &ix, &pTheAttrName)) )
{
//Get variant value of named attribute
VARIANT pVal;
if ( S_OK == (pQualifierSet->Get(pTheAttrName, 0, &pVal, NULL)) )
{
//Get attribute set for column
IWbemQualifierSetPtr pQualifierSet2 = NULL;
if ( S_OK != (lpISAMTableDef->pSingleTable->GetPropertyQualifierSet(pTheAttrName, &pQualifierSet2)) )
{
SysFreeString(pTheAttrName);
return SQL_ERROR;
}
//Get CIMTYPE String
VARIANT pVal2;
BSTR syntaxStr = NULL;
BOOL fClearpVal2 = FALSE;
BSTR cimTypeBSTR = SysAllocString(WBEMDR32_L_CIMTYPE);
if ( S_OK == (pQualifierSet2->Get(cimTypeBSTR, 0, &pVal2, NULL)) )
{
if (pVal2.bstrVal)
syntaxStr = pVal2.bstrVal;
fClearpVal2 = TRUE;
}
SysFreeString(cimTypeBSTR);
//Get the MAX String
VARIANT pVal3;
SDWORD maxLenVal = 0;
BOOL fClearpVal3 = FALSE;
BSTR maxBSTR = SysAllocString(WBEMDR32_L_MAX);
if ( S_OK == (pQualifierSet->Get(maxBSTR, 0, &pVal3, NULL)) )
{
maxLenVal = pVal3.iVal;
fClearpVal3 = TRUE;
}
SysFreeString(maxBSTR);
//Decode variant value, as we do not know actual size of value
//beforehand we will create buffers in increments of 200 bytes
//until we can get the value with truncation
ULONG cwAttemptToGetValue = 0;
ULONG wBufferLen = 0;
char* buffer = NULL;
SDWORD cbValue;
SWORD err = ISAM_TRUNCATION;
while ( err == ISAM_TRUNCATION )
{
if (buffer)
delete buffer;
wBufferLen = 200 * (++cwAttemptToGetValue);
buffer = new char [wBufferLen + 1];
buffer[0] = 0;
err = ISAMGetValueFromVariant(pVal, SQL_C_CHAR, buffer, wBufferLen, &cbValue, 0, syntaxStr, maxLenVal);
}
VariantClear (&pVal);
if (fClearpVal2)
VariantClear (&pVal2);
if (fClearpVal3)
VariantClear (&pVal3);
//Check for error
if (err != NO_ISAM_ERR)
{
lpISAMTableDef->lpISAM->errcode = err;
SafeArrayUnlock(rgNames);
SafeArrayDestroy(rgNames);
SysFreeString(pTheAttrName);
delete buffer;
return SQL_ERROR;
}
//Once we have the name and value of the attribute let us try and add
//it to the output buffer
//First try and save the attribute name
//Save old number of bytes copied so that if truncation
//occurs we can roll back to original state
SDWORD pdbOldValue = cbBytesCopied;
//If this is not the first attribute in the list
//we must separate the attribute/value pairs with "\n" character
if ( (cbValueMax - cbBytesCopied) && cbBytesCopied)
{
pAttrStr[cbBytesCopied++] = '\n';
}
//Now add in attribute name
//first convert it from a BSTR to a char*
char* lpTheAttrString = NULL;
ULONG cLength = 0;
if (pTheAttrName)
{
cLength = wcslen(pTheAttrName);
lpTheAttrString = new char [cLength + 1];
lpTheAttrString[0] = 0;
wcstombs(lpTheAttrString, pTheAttrName, cLength);
lpTheAttrString[cLength] = 0;
}
BOOL fOutOfBufferSpace = FALSE;
err = ISAMFormatCharParm (lpTheAttrString, fOutOfBufferSpace,
pAttrStr, cbValueMax, &cbBytesCopied, FALSE);
delete lpTheAttrString;
//Now add in value
if (err == NO_ISAM_ERR)
{
err = ISAMFormatCharParm (buffer, fOutOfBufferSpace,
pAttrStr, cbValueMax, &cbBytesCopied, FALSE);
}
delete buffer;
buffer = NULL;
if (err != NO_ISAM_ERR)
{
//Truncation took place so rollback
cbBytesCopied = pdbOldValue;
//Null terminate
pAttrStr[cbBytesCopied] = 0;
SysFreeString(pTheAttrName);
return SQL_SUCCESS_WITH_INFO;
}
//Null terminate
pAttrStr[cbBytesCopied] = 0;
}
else
{
//Error, tidy up and then quit
SafeArrayUnlock(rgNames);
SafeArrayDestroy(rgNames);
return SQL_ERROR;
}
SysFreeString(pTheAttrName);
}
else
{
//Error, tidy up and then quit
SafeArrayUnlock(rgNames);
SafeArrayDestroy(rgNames);
return SQL_ERROR;
}
}
//Tidy Up
SafeArrayUnlock(rgNames);
SafeArrayDestroy(rgNames);
return SQL_SUCCESS;
}
/***************************************************************************/
UWORD INTFUNC GetNumberOfColumnsInTable(LPISAMTABLEDEF lpISAMTableDef)
{
//Get number of columns
ClassColumnInfoBase* cInfoBase = lpISAMTableDef->pColumnInfo;
if ( !cInfoBase->IsValid() )
{
return 0;
}
return cInfoBase->GetNumberOfColumns();
}
/***************************************************************************/
/* This method checks if a string contains any */
/* character preference control characters */
/* such as %, _, \\ */
/* */
/* this method was cut and pasted out of an */
/* existing class and converted into a function */
static BOOL INTFUNC IsRegularExpression(char* lpPattern)
{
//First check if input string is valid and if it has any
//characters to check for
ULONG cLen = 0;
char m_cWildcard = '%';
char m_cAnySingleChar = '_';
char m_cEscapeSeq = '\\';
if (lpPattern)
cLen = strlen (lpPattern);
ULONG iIndex = 0;
if (cLen)
{
//Go through string checking for the 'wildcard' and 'single char' characters
while (iIndex < cLen)
{
//Check for 'wildcard' and 'single char' characters
if ( (lpPattern[iIndex] == m_cWildcard) || (lpPattern[iIndex] == m_cAnySingleChar) )
{
return TRUE;
}
//Skip any characters which are preceeded by escape sequence character
if ( lpPattern[iIndex] == m_cEscapeSeq)
{
//skip escape character and next one
iIndex++;
}
//Increment index in string
iIndex++;
}
}
else
{
//No character to check
return FALSE;
}
//If you reach here then input string must not be a regular expression
return FALSE;
}
/***************************************************************************/
CNotifyTableNames ::CNotifyTableNames(LPISAMTABLELIST lpTblList)
{
//Initialize reference count and backpointer to table list
m_cRef = 0;
lpISAMTableList = lpTblList;
//create mutex (no owed by anyone yet)
m_mutex = CreateMutex(NULL, FALSE, NULL);
}
/***************************************************************************/
CNotifyTableNames :: ~CNotifyTableNames()
{
//Tidy Up
CloseHandle(m_mutex);
}
/***************************************************************************/
STDMETHODIMP_(ULONG) CNotifyTableNames :: AddRef(void)
{
return ++m_cRef;
}
/***************************************************************************/
STDMETHODIMP_(ULONG) CNotifyTableNames :: Release(void) // FOLLOWUP: why is the decrement commented out?
{
// if (--m_cRef != 0)
// {
// return m_cRef;
// }
//If you reached this point the reference count is zero
//Therefore we have got all information back
lpISAMTableList->iIndex = lpISAMTableList->pTblList->GetHeadPosition();
lpISAMTableList->fGotAllInfo = TRUE;
delete this;
return 0;
}
/***************************************************************************/
STDMETHODIMP CNotifyTableNames :: QueryInterface(REFIID riid, LPVOID FAR* ppv)
{
*ppv = NULL;
if (IID_IUnknown == riid || IID_IWbemObjectSink == riid)
*ppv = this;
if (*ppv == NULL)
return ResultFromScode(E_NOINTERFACE);
return NOERROR;
}
/***************************************************************************/
STDMETHODIMP_(SCODE) CNotifyTableNames :: Notify(long lObjectCount, IWbemClassObject** pObjArray)
{
//remember to mutex protect writing to table list
WaitForSingleObject(m_mutex, INFINITE);
for (long i = 0; i < lObjectCount; i++)
{
if (pObjArray[i])
{
pObjArray[i]->AddRef();
lpISAMTableList->pTblList->AddTail(pObjArray[i]);
}
}
ReleaseMutex(m_mutex);
return WBEM_NO_ERROR;
}
/***************************************************************************/
/* Setups up ISAM structure which stores data-source information */
SWORD INTFUNC ISAMOpen(LPUSTR lpszServer,
LPUSTR lpszDatabase,
LPUSTR lpszDSN,
// WBEM_LOGIN_AUTHENTICATION loginMethod,
LPUSTR lpszUsername,
LPUSTR lpszPassword,
LPUSTR lpszLocale,
LPUSTR lpszAuthority,
BOOL fSysProps,
CMapStringToOb *pNamespaceMap,
LPISAM FAR *lplpISAM,
LPUSTR lpszErrorMessage,
BOOL fOptimization,
BOOL fImpersonation,
BOOL fPassthroughOnly,
BOOL fIntpretEmptPwdAsBlk)
{
s_lstrcpy(lpszErrorMessage, "");
// ODBCTRACE("\nWBEM ODBC Driver : ISAMOpen\n");
//Extra check for table qualifier
if (!lpszDatabase || !s_lstrlen (lpszDatabase)) // need to check in args here too
{
LoadString(s_hModule, ISAM_NS_QUALMISSING, (LPSTR)lpszErrorMessage,
MAX_ERROR_LENGTH+1);
*lplpISAM = NULL;
return ISAM_NS_QUALMISSING;
}
HGLOBAL h;
LPISAM lpISAM;
h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (ISAM));
if (h == NULL || (lpISAM = (LPISAM) GlobalLock (h)) == NULL) {
if (h)
GlobalFree(h);
LoadString(s_hModule, ISAM_MEMALLOCFAIL, (LPSTR)lpszErrorMessage,
MAX_ERROR_LENGTH+1);
*lplpISAM = NULL;
return ISAM_MEMALLOCFAIL;
}
lpISAM->cSQLTypes = NumTypes();
lpISAM->SQLTypes = SQLTypes;
lpISAM->fTxnCapable = SQL_TC_NONE;
lpISAM->fSchemaInfoTransactioned = FALSE;
lpISAM->fMultipleActiveTxn = FALSE;
lpISAM->fTxnIsolationOption = SQL_TXN_READ_UNCOMMITTED;
lpISAM->fDefaultTxnIsolation = SQL_TXN_READ_UNCOMMITTED;
lpISAM->udwNetISAMVersion = 0;
lpISAM->hKernelApi = LoadLibrary("KERNEL32.DLL");
lpISAM->netConnection = NULL;
lpISAM->netISAM = NET_OPAQUE_INVALID;
lpISAM->fCaseSensitive = FALSE;
s_lstrcpy(lpISAM->szName, "");
s_lstrcpy(lpISAM->szVersion, "");
lpISAM->cbMaxTableNameLength = 0;
lpISAM->cbMaxColumnNameLength = 0;
//WBEM Client Recognition variables
//(dummy values which will be overridden)
lpISAM->dwAuthLevel = 0;
lpISAM->dwImpLevel = 0;
lpISAM->gpAuthIdentity = NULL;
lpISAM->pNamespaceMap = pNamespaceMap;
s_lstrcpy (lpISAM->szServer, lpszServer);
s_lstrcpy (lpISAM->szDatabase, lpszDatabase);
s_lstrcpy (lpISAM->szUser, lpszUsername);
s_lstrcpy (lpISAM->szPassword, lpszPassword);
s_lstrcpy (lpISAM->szRootDb, "root");
//Flags for cloaking
lpISAM->fIsLocalConnection = IsLocalServer((LPSTR) lpszServer);
lpISAM->fW2KOrMore = IsW2KOrMore();
//Make copies of locale and authority
lpISAM->m_Locale = NULL;
if (lpszLocale)
{
int localeLen = lstrlen((char*)lpszLocale);
lpISAM->m_Locale = new char [localeLen + 1];
(lpISAM->m_Locale)[0] = 0;
lstrcpy(lpISAM->m_Locale, (char*)lpszLocale);
}
lpISAM->m_Authority = NULL;
if (lpszAuthority)
{
int authLen = lstrlen((char*)lpszAuthority);
lpISAM->m_Authority = new char [authLen + 1];
(lpISAM->m_Authority)[0] = 0;
lstrcpy(lpISAM->m_Authority, (char*)lpszAuthority);
}
lpISAM->fOptimization = fOptimization;
lpISAM->fSysProps = fSysProps;
lpISAM->fPassthroughOnly = fPassthroughOnly;
lpISAM->fIntpretEmptPwdAsBlank = fIntpretEmptPwdAsBlk;
//Check if impersonation is requested
lpISAM->Impersonate = NULL;
if (fImpersonation)
{
//Now check if impersonation is necessary
//only if connecting locally
if (IsLocalServer((LPSTR) lpszServer))
{
lpISAM->Impersonate = new ImpersonationManager(lpISAM->szUser, lpISAM->szPassword, lpISAM->m_Authority);
}
else
{
ODBCTRACE("\nWBEM ODBC Driver : Server not detected as local, not impersonating\n");
}
}
lpISAM->errcode = NO_ISAM_ERR;
//SAI new - make sure there is nothing in old
//ISAM before you assign to it
if (*lplpISAM)
ISAMClose(*lplpISAM);
*lplpISAM = lpISAM;
//Check if impersonation worked
if (fImpersonation && lpISAM->Impersonate)
{
if ( ! lpISAM->Impersonate->CanWeImpersonate() )
{
lpISAM->pNamespaceMap = NULL; //protect against deleting namespace map
ISAMClose(lpISAM);
*lplpISAM = NULL;
return ISAM_ERROR;
}
}
return NO_ISAM_ERR;
}
/***************************************************************************/
/* Creates a communication channel to the Gateway Server */
// Checked for SetInterfaceSecurityEx on IWbemServices
void INTFUNC ISAMGetGatewayServer(IWbemServicesPtr& pGateway, LPISAM lpISAM, LPUSTR lpQualifierName,
SWORD cbQualifierName)
{
ThreadLocaleIdManager myThread(lpISAM);
//First get the locator interface
IWbemLocator* pLocator = NULL;
SCODE sc = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER , IID_IWbemLocator, (void**) (&pLocator) );
//Bug fix for dbWeb
if ( FAILED(sc) )
{
//If you fail, initialize OLE and try again
OleInitialize(0);
sc = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER , IID_IWbemLocator, (void**) (&pLocator) );
}
if ( FAILED(sc) )
{
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 2 : Error position 1\n");
return;
}
//Get user and password fields
//Get handle to gateway server interface
pGateway = NULL;
long refcount = 0;
//Check if we want the default database or something else
//We will be building the fully qualified database pathname
//so we work out some lengths first
SWORD cbServerLen = (SWORD) _mbstrlen((LPSTR)lpISAM->szServer);
//RAID 57673 WMI has changed such that if you
//connect locally and pass a username and password
//it will fail
//Check for local connection
// CBString myServerStr;
// myServerStr.AddString( (LPSTR)lpISAM->szServer, FALSE );
// CServerLocationCheck myCheck (myServerStr);
BOOL fIsLocalConnection = lpISAM->fIsLocalConnection;//myCheck.IsLocal();
//Used to store the fully qualified database pathname
wchar_t pWcharName [MAX_DATABASE_NAME_LENGTH+1];
pWcharName[0] = 0;
if (cbQualifierName)
{
//We want something else
//We need to prepend server name to qualifier name
//Need to make sure everything fits in buffer size
if ( (cbServerLen + cbQualifierName + 1) > MAX_DATABASE_NAME_LENGTH )
{
pLocator->Release();
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 2 : Error position 2\n");
return;
}
CBString namespaceBSTR;
//Construct string
if (cbServerLen)
{
char pCharName [MAX_DATABASE_NAME_LENGTH+1];
pCharName[0] = 0;
sprintf (pCharName, "%s\\%s", (LPUSTR)lpISAM->szServer, (LPSTR)lpQualifierName);
CString myText;
myText.Format("\nWBEM ODBC Driver : Connecting using : %s\n", pCharName);
ODBCTRACE(myText);
//Convert to wide string
namespaceBSTR.AddString(pCharName, FALSE);
}
else
{
if (lpQualifierName)
{
namespaceBSTR.AddString((LPSTR)lpQualifierName, FALSE, cbQualifierName);
}
}
//Convert wide characters to BSTR for DCOM
//----------------------------------------
CBString userBSTR;
if (!fIsLocalConnection)
userBSTR.AddString((LPSTR)lpISAM->szUser, FALSE);
CBString passwdBSTR;
if (!fIsLocalConnection)
passwdBSTR.AddString((LPSTR)lpISAM->szPassword, lpISAM->fIntpretEmptPwdAsBlank);
CBString localeBSTR;
CBString authorityBSTR;
localeBSTR.AddString(lpISAM->m_Locale, FALSE);
//Get the local and authority fields
authorityBSTR.AddString(lpISAM->m_Authority, FALSE);
sc = pLocator->ConnectServer (namespaceBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(), localeBSTR.GetString(), 0, authorityBSTR.GetString(), NULL, &pGateway);
if (sc == S_OK)
{
sc = GetAuthImp( pGateway, &(lpISAM->dwAuthLevel), &(lpISAM->dwImpLevel));
if(sc == S_OK)
{
if (lpISAM->dwAuthLevel > RPC_C_AUTHN_LEVEL_NONE)
lpISAM->dwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
if ( lpISAM->gpAuthIdentity )
{
WbemFreeAuthIdentity( lpISAM->gpAuthIdentity );
lpISAM->gpAuthIdentity = NULL;
}
sc = ISAMSetCloaking1( pGateway,
lpISAM->fIsLocalConnection,
lpISAM->fW2KOrMore,
lpISAM->dwAuthLevel,
lpISAM->dwImpLevel,
authorityBSTR.GetString(),
userBSTR.GetString(),
passwdBSTR.GetString(),
&(lpISAM->gpAuthIdentity) );
/*
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(pGateway, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
}
else
{
sc = SetInterfaceSecurityEx(pGateway, authorityBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(),
lpISAM->dwAuthLevel, lpISAM->dwImpLevel, EOAC_NONE, &(lpISAM->gpAuthIdentity), &gpPrincipal );
}
*/
}
}
}
else
{
//We want the default database
//Get default connection from LPISAM == <root>\default
//We need to prepend server name to <root>\default
//Need to make sure everything fits in buffer size
SWORD cbRootLen = strlen ((LPSTR)lpISAM->szRootDb);
if ( (cbServerLen + cbRootLen + 9) > MAX_DATABASE_NAME_LENGTH)
{
pLocator->Release();
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 2 : Error position 3\n");
return;
}
//Construct string
CBString namespaceBSTR;
if (cbServerLen)
{
char pCharName [MAX_DATABASE_NAME_LENGTH+1];
pCharName[0] = 0;
sprintf (pCharName, "%s\\%s\\default", (LPUSTR)lpISAM->szServer, (LPSTR)lpISAM->szRootDb);
//Convert to wide string
namespaceBSTR.AddString(pCharName, FALSE);
}
else
{
if ((LPSTR)lpISAM->szRootDb)
{
char pCharName [MAX_DATABASE_NAME_LENGTH+1];
pCharName[0] = 0;
sprintf (pCharName, "%s\\default", (LPSTR)lpISAM->szRootDb);
namespaceBSTR.AddString(pCharName, FALSE);
}
}
//Convert wide characters to BSTR for DCOM
//----------------------------------------
CBString userBSTR;
if (!fIsLocalConnection)
userBSTR.AddString((LPSTR)lpISAM->szUser, FALSE);
CBString passwdBSTR;
if (!fIsLocalConnection)
passwdBSTR.AddString((LPSTR)lpISAM->szPassword, lpISAM->fIntpretEmptPwdAsBlank);
CBString localeBSTR;
CBString authorityBSTR;
//Get the local and authority fields
localeBSTR.AddString(lpISAM->m_Locale, FALSE);
authorityBSTR.AddString(lpISAM->m_Authority, FALSE);
sc = pLocator->ConnectServer (namespaceBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(), localeBSTR.GetString(), 0, authorityBSTR.GetString(), NULL, &pGateway);
if (sc == S_OK)
{
sc = GetAuthImp( pGateway, &(lpISAM->dwAuthLevel), &(lpISAM->dwImpLevel));
if(sc == S_OK)
{
if (lpISAM->dwAuthLevel > RPC_C_AUTHN_LEVEL_NONE)
lpISAM->dwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
if ( lpISAM->gpAuthIdentity )
{
WbemFreeAuthIdentity( lpISAM->gpAuthIdentity );
lpISAM->gpAuthIdentity = NULL;
}
sc = ISAMSetCloaking1( pGateway,
lpISAM->fIsLocalConnection,
lpISAM->fW2KOrMore,
lpISAM->dwAuthLevel,
lpISAM->dwImpLevel,
authorityBSTR.GetString(),
userBSTR.GetString(),
passwdBSTR.GetString(),
&(lpISAM->gpAuthIdentity) );
/*
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(pGateway, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
}
else
{
sc = SetInterfaceSecurityEx(pGateway, authorityBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(),
lpISAM->dwAuthLevel, lpISAM->dwImpLevel, EOAC_NONE, &(lpISAM->gpAuthIdentity), &gpPrincipal);
}
*/
}
}
}
//We have now finished with the locator so we can release it
pLocator->Release();
if ( FAILED(sc) )
{
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 2 : Error position 4\n");
return;
}
}
/***************************************************************************/
/* Creates a communication channel to the Gateway Server */
// Checked for SetInterfaceSecurityEx on IWbemServices
void INTFUNC ISAMGetGatewayServer(IWbemServicesPtr& pGateway,
LPUSTR lpServerName,
// WBEM_LOGIN_AUTHENTICATION loginMethod,
LPUSTR objectPath, LPUSTR lpUserName, LPUSTR lpPassword, LPUSTR lpLocale, LPUSTR lpAuthority,
DWORD &dwAuthLevel, DWORD &dwImpLevel, BOOL fIntpretEmptPwdAsBlank, COAUTHIDENTITY** ppAuthIdent)
{
ThreadLocaleIdManager myThread(lpLocale);
*ppAuthIdent = NULL;
IWbemLocator* pLocator = NULL;
SCODE sc = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER , IID_IWbemLocator, (void**) (&pLocator) );
if ( FAILED(sc) )
{
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 1 : Error position 1\n");
return;
}
pGateway = NULL;
//SAI ADDED
long refcount = 0;
//We need to prepend server name to object path
//Need to make sure everything fits in buffer size
SWORD cbServerLen = 0;
SWORD cbObjPathLen = 0;
if (lpServerName)
cbServerLen = (SWORD) _mbstrlen( (LPSTR)lpServerName);
//RAID 57673 WMI has changed such that if you
//connect locally and pass a username and password
//it will fail
//Check for local connection
BOOL fIsLocalConnection = IsLocalServer((LPSTR) lpServerName);
if (objectPath)
cbObjPathLen = strlen ( (LPSTR)objectPath);
if ( (cbServerLen + cbObjPathLen + 1) > MAX_DATABASE_NAME_LENGTH)
{
pLocator->Release();
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 1 : Error position 2\n");
return;
}
//Construct string (namespace)
CBString namespaceBSTR;
if (cbServerLen)
{
char pCharBuff [MAX_DATABASE_NAME_LENGTH + 1];
pCharBuff[0] = 0;
sprintf (pCharBuff, "%s\\%s", (LPUSTR)lpServerName, (LPSTR)objectPath);
CString myText;
myText.Format("\nWBEM ODBC Driver : Connecting using : %s\n", pCharBuff);
ODBCTRACE(myText);
//Convert to wide string
namespaceBSTR.AddString(pCharBuff, FALSE);
}
else
{
if (objectPath)
{
namespaceBSTR.AddString((LPSTR)objectPath, FALSE);
}
}
//Get user and password fields
CBString localeBSTR;
CBString authorityBSTR;
localeBSTR.AddString((char*)lpLocale, FALSE);
authorityBSTR.AddString((char*)lpAuthority, FALSE);
//Convert wide characters to BSTR for DCOM
//----------------------------------------
CBString userBSTR;
if (!fIsLocalConnection)
userBSTR.AddString((LPSTR)lpUserName, FALSE);
CBString passwdBSTR;
if (!fIsLocalConnection)
passwdBSTR.AddString((LPSTR)lpPassword, fIntpretEmptPwdAsBlank);
sc = pLocator->ConnectServer (namespaceBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(), localeBSTR.GetString(), 0, authorityBSTR.GetString(), NULL, &pGateway);
if (sc == S_OK)
{
sc = GetAuthImp( pGateway, &dwAuthLevel, &dwImpLevel);
if(sc == S_OK)
{
if (dwAuthLevel > RPC_C_AUTHN_LEVEL_NONE)
dwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
sc = ISAMSetCloaking1( pGateway,
fIsLocalConnection,
IsW2KOrMore(),
dwAuthLevel,
dwImpLevel,
authorityBSTR.GetString(),
userBSTR.GetString(),
passwdBSTR.GetString(),
ppAuthIdent );
/*
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(pGateway, dwAuthLevel, dwImpLevel);
}
else
{
sc = SetInterfaceSecurityEx(pGateway, authorityBSTR.GetString(), userBSTR.GetString(), passwdBSTR.GetString(),
dwAuthLevel, dwImpLevel, EOAC_NONE, ppAuthIdent, &gpPrincipal);
}
*/
}
}
pLocator->Release();
if ( FAILED(sc) )
{
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetGatewayServer version 1 : Error position 3\n");
return;
}
}
/***************************************************************************/
/* Function to fix MSQuery bug which appends */
/* a \ infront of _ characters in table names */
void ISAM_MSQueryBugFix(LPSTR lpOrigPattern, LPSTR lpNewPattern, SWORD &cbPattern)
{
SWORD iNewPatternIndex = 0;
for (SWORD iIndex = 0; iIndex < cbPattern; iIndex++)
{
//Check for '\' character follwed by a '_'
if ( (lpOrigPattern[iIndex] == '\\') && (lpOrigPattern[iIndex + 1] == '_') )
{
//Skip underscore character
iIndex++;
}
//Copy character
lpNewPattern[iNewPatternIndex++] = lpOrigPattern[iIndex];
}
//Null terminate new string
lpNewPattern[iNewPatternIndex] = 0;
//Update length of new string
cbPattern = iNewPatternIndex;
}
/***************************************************************************/
/* Stores the necessary information to obtain a list of database tables */
/* with match the search pattern */
SWORD INTFUNC ISAMGetTableList (LPISAM lpISAM, LPUSTR lpPattern, SWORD cbPattern,
LPUSTR lpQualifierName, SWORD cbQualifierName,
LPISAMTABLELIST FAR *lplpISAMTableList, BOOL fWantSysTables, BOOL fEmptyList)
{
//Local Variables
HGLOBAL h;
LPISAMTABLELIST lpISAMTableList;
lpISAM->errcode = NO_ISAM_ERR;
//Allocate memory for table list structure on the heap
h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (ISAMTABLELIST));
if (h == NULL || (lpISAMTableList = (LPISAMTABLELIST) GlobalLock (h)) == NULL)
{
if (h)
GlobalFree(h);
lpISAM->errcode = ISAM_MEMALLOCFAIL;
return ISAM_MEMALLOCFAIL;
}
//Check table name
//There is a bug in MSQuery which appends extra \ character(s)
//to table names which have underscore(s)
//If this is the case we remove the \ character(s)
char* lpNewPattern = new char [cbPattern + 1];
ISAM_MSQueryBugFix((LPSTR)lpPattern, lpNewPattern, cbPattern);
//Copy search pattern
_fmemcpy(lpISAMTableList->lpPattern, lpNewPattern, cbPattern);
//Save search pattern length
lpISAMTableList->cbPattern = cbPattern;
//Delete tempory buffer
delete lpNewPattern;
//Copy qualifer name if it is non-null and not the default database
lpISAMTableList->lpQualifierName[0] = 0;
if (cbQualifierName)
{
strncpy((LPSTR)lpISAMTableList->lpQualifierName, (LPSTR)lpQualifierName, cbQualifierName);
}
else
{
cbQualifierName = 0;
}
lpISAMTableList->lpQualifierName[cbQualifierName] = 0;
#ifdef TESTING
//Remember to remove this printf
printf ("Qualifier = %s", (char*)lpISAMTableList->lpQualifierName );
#endif
//Is this table list going to be an empty one because
//we requested a table type other than TABLE or SYSTEM TABLE ?
lpISAMTableList->fEmptyList = fEmptyList;
//Do we want System Tables ?
lpISAMTableList->fWantSysTables = fWantSysTables;
//Save the qualifier length
lpISAMTableList->cbQualifierName = cbQualifierName;
//Save flag to indicate if this is the first time table list is accessed
lpISAMTableList->fFirstTime = TRUE;
//Save information to create a context to database
lpISAMTableList->lpISAM = lpISAM;
//Initialize pointer to enumerated list of tables
lpISAMTableList->pTblList = new CPtrList();
//Create an object to store WbemServices pointer
lpISAMTableList->pGateway2 = new CSafeWbemServices();
//Setup output parameter
*lplpISAMTableList = lpISAMTableList;
lpISAMTableList->netISAMTableList = NET_OPAQUE_INVALID;
return NO_ISAM_ERR;
}
/***************************************************************************/
/* Stores the necessary information to obtain a list of database qualifiers */
SWORD INTFUNC ISAMGetQualifierList(LPISAM lpISAM, LPISAMQUALIFIERLIST FAR *lplpISAMQualifierList)
{
//Local Variables
HGLOBAL h;
LPISAMQUALIFIERLIST lpISAMQualifierList;
lpISAM->errcode = NO_ISAM_ERR;
//Allocate memory for qualifier list structure on heap
h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (ISAMQUALIFIERLIST));
if (h == NULL || (lpISAMQualifierList = (LPISAMQUALIFIERLIST) GlobalLock (h)) == NULL)
{
if (h)
GlobalFree(h);
lpISAM->errcode = ISAM_MEMALLOCFAIL;
return ISAM_MEMALLOCFAIL;
}
//Save flag to indicate if this is the first qualifier list is accessed
lpISAMQualifierList->fFirstTime = TRUE;
//Save information to create a context to database
lpISAMQualifierList->lpISAM = lpISAM;
//Setup output parameter
*lplpISAMQualifierList = lpISAMQualifierList;
return NO_ISAM_ERR;
}
/***************************************************************************/
/* Retrieves next table name from table list */
// Checked for SetInterfaceSecurityEx on IWbemServices
SWORD INTFUNC ISAMGetNextTableName(UDWORD fSyncMode, LPISAMTABLELIST lpISAMTableList, LPUSTR lpTableName, LPUSTR lpTableType)
{
//Initialize, no errors found yet
lpISAMTableList->lpISAM->errcode = NO_ISAM_ERR;
IWbemClassObject* pSingleTable = NULL;
BOOL fReleaseSingleTable = FALSE;
//Check if we have detacted an empty table list due
//to the fact that we requested a table type other than TABLE
if (lpISAMTableList->fEmptyList)
{
lpISAMTableList->lpISAM->errcode = ISAM_EOF;
return ISAM_EOF;
}
//We need to get the next table in the list from the LPISAMTABLELIST
//However, if this is the first time this function is called, no table list
//will be present, and we will need to get it from the Gateway Server
// First time through?
if (lpISAMTableList->fFirstTime)
{
//Clear out any old values
if (lpISAMTableList->pTblList && lpISAMTableList->pTblList->GetCount())
{
POSITION thePos = NULL;
for ( thePos = lpISAMTableList->pTblList->GetHeadPosition(); thePos != NULL; )
{
IWbemClassObject* pTheValue = (IWbemClassObject*) lpISAMTableList->pTblList->GetNext(thePos);
pTheValue->Release();
}
lpISAMTableList->pTblList->RemoveAll();
}
//Initialize
if (lpISAMTableList->pGateway2)
lpISAMTableList->pGateway2->Invalidate();
lpISAMTableList->iIndex = NULL;
lpISAMTableList->fFirstTime = FALSE;
lpISAMTableList->fGotAllInfo = FALSE;
//Get list of tables from the
//Gateway Server which match search pattern
//First get the Gateway Interface
//remember to Release it after use
lpISAMTableList->pGateway2->SetInterfacePtr
(lpISAMTableList->lpISAM, (LPUSTR)lpISAMTableList->lpQualifierName, lpISAMTableList->cbQualifierName);
//Check if a valid interface was returned
if ( ! lpISAMTableList->pGateway2->IsValid() )
{
//Could not create a Gateway Interface, return error
lpISAMTableList->lpISAM->errcode = ISAM_PROVIDERFAIL;
return ISAM_PROVIDERFAIL;
}
//First check if we need to get one table or a list of tables
//by using the pattern matcher class
if ( IsRegularExpression((char*)lpISAMTableList->lpPattern) )
{
//We want a table LIST
//We enumerate for tables, the resultant enumeration will be allocated on
//the HEAP by the Gateway Server and referneced by pEnum
BSTR emptySuperClass = SysAllocString(L"");
//Check if we want to get list asynchronously
if (fSyncMode == SQL_ASYNC_ENABLE_ON)
{
//Create notification object
CNotifyTableNames* pNotifyTable = new CNotifyTableNames(lpISAMTableList);
IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAMTableList->lpISAM->m_Locale);
IWbemServicesPtr myServicesPtr = NULL;
ISAMGetIWbemServices(lpISAMTableList->lpISAM, *(lpISAMTableList->pGateway2), myServicesPtr);
//cloaking
BOOL fIsLocalConnection = lpISAMTableList->lpISAM->fIsLocalConnection;
if ( fIsLocalConnection && (lpISAMTableList->lpISAM->fW2KOrMore) )
{
WbemSetDynamicCloaking(myServicesPtr, lpISAMTableList->lpISAM->dwAuthLevel, lpISAMTableList->lpISAM->dwImpLevel);
}
if ( FAILED(myServicesPtr->CreateClassEnumAsync
(_bstr_t(), WBEM_FLAG_DEEP, pContext, pNotifyTable)) )
{
//Tidy Up
lpISAMTableList->pGateway2->Invalidate();
SysFreeString(emptySuperClass);
if (pContext)
pContext->Release();
//Flag error
lpISAMTableList->lpISAM->errcode = ISAM_TABLELISTFAIL;
return ISAM_TABLELISTFAIL;
}
//Tidy Up
SysFreeString(emptySuperClass);
if (pContext)
pContext->Release();
//BREAK OUT OF THIS FUNCTION
return ISAM_STILL_EXECUTING;
}
IEnumWbemClassObjectPtr pEnum = NULL;
IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAMTableList->lpISAM->m_Locale);
IWbemServicesPtr myServicesPtr = NULL;
ISAMGetIWbemServices(lpISAMTableList->lpISAM, *(lpISAMTableList->pGateway2), myServicesPtr);
//cloaking
BOOL fIsLocalConnection = lpISAMTableList->lpISAM->fIsLocalConnection;
if ( fIsLocalConnection && (lpISAMTableList->lpISAM->fW2KOrMore) )
{
WbemSetDynamicCloaking(myServicesPtr, lpISAMTableList->lpISAM->dwAuthLevel, lpISAMTableList->lpISAM->dwImpLevel);
}
HRESULT hRes = myServicesPtr->CreateClassEnum
(_bstr_t(), WBEM_FLAG_DEEP, pContext, &pEnum);
if (pContext)
pContext->Release();
ISAMSetCloaking2(pEnum,
fIsLocalConnection,
lpISAMTableList->lpISAM->fW2KOrMore,
lpISAMTableList->lpISAM->dwAuthLevel,
lpISAMTableList->lpISAM->dwImpLevel,
lpISAMTableList->lpISAM->gpAuthIdentity);
/*
if ( fIsLocalConnection && (lpISAMTableList->lpISAM->fW2KOrMore) )
{
WbemSetDynamicCloaking(pEnum, lpISAMTableList->lpISAM->dwAuthLevel, lpISAMTableList->lpISAM->dwImpLevel);
}
else
{
SetInterfaceSecurityEx(pEnum, lpISAMTableList->lpISAM->gpAuthIdentity, gpPrincipal, lpISAMTableList->lpISAM->dwAuthLevel, lpISAMTableList->lpISAM->dwImpLevel);
}
*/
//Tidy Up
SysFreeString(emptySuperClass);
if (FAILED(hRes))
{
//Tidy Up
lpISAMTableList->pGateway2->Invalidate();
//Flag error
lpISAMTableList->lpISAM->errcode = ISAM_TABLELISTFAIL;
return ISAM_TABLELISTFAIL;
}
//Now we have the table enumeration get the first item
ULONG puReturned;
SCODE sc1 = pEnum->Reset();
SCODE sc2 = pEnum->Next(-1, 1, &pSingleTable, &puReturned);
BOOL f1 = (S_OK == sc1) ? TRUE : FALSE;
BOOL f2 = ( S_OK == sc2) ? TRUE : FALSE;
if ( (pEnum == NULL) || (!f1) || (!f2)
)
{
//Tidy Up
lpISAMTableList->pGateway2->Invalidate();
//Flag error
lpISAMTableList->lpISAM->errcode = ISAM_EOF;
return ISAM_EOF;
}
else
{
fReleaseSingleTable = TRUE;
//Place any remaining tables in the pTblList
IWbemClassObject* pSingleTable2 = NULL;
while (S_OK == pEnum->Next(-1, 1, &pSingleTable2, &puReturned))
{
lpISAMTableList->pTblList->AddTail(pSingleTable2);
}
//Set index to correct start position for next items
lpISAMTableList->iIndex = lpISAMTableList->pTblList->GetHeadPosition();
}
}
else
{
//We want a SINGLE table
//Set this flag in case you are asynchronously requesting
//for 1 table !!!
lpISAMTableList->fGotAllInfo = TRUE;
//Create a pointer to store table class definition
//the class definition object will be CREATED on the HEAP
//by the GetClass function
pSingleTable = NULL;
LONG cLength = lstrlen((char*)lpISAMTableList->lpPattern);
wchar_t* pWClassName = new wchar_t [cLength + 1];
pWClassName[0] = 0;
int iItemsCopied = mbstowcs(pWClassName, (char*)lpISAMTableList->lpPattern, cLength);
pWClassName[cLength] = 0;
BSTR pTheTableName = SysAllocStringLen(pWClassName, cLength);
IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAMTableList->lpISAM->m_Locale);
IWbemServicesPtr myServicesPtr = NULL;
ISAMGetIWbemServices(lpISAMTableList->lpISAM, *(lpISAMTableList->pGateway2), myServicesPtr);
SCODE sStatus = myServicesPtr->GetObject(pTheTableName, 0, pContext, &pSingleTable, NULL);
if (pContext)
pContext->Release();
fReleaseSingleTable = TRUE;
SysFreeString(pTheTableName);
delete pWClassName;
if ( FAILED(sStatus) || (!pSingleTable) )
{
//Failed to get named class definition
//Tidy Up
lpISAMTableList->pGateway2->Invalidate();
//Flag error
lpISAMTableList->lpISAM->errcode = ISAM_EOF;
return ISAM_EOF;
}
}
}
else
{
//Get next item in enumeration if applicable
//Check if function is asynchronous, if so
//we must first check the fGotAllInfo flag
//if we have all the info we can get the next table
//we assign the pSingleTable pointer
if ( (fSyncMode == SQL_ASYNC_ENABLE_ON) && (!lpISAMTableList->fGotAllInfo) )
return ISAM_STILL_EXECUTING;
//Get Next
if (lpISAMTableList->iIndex)
{
pSingleTable = (IWbemClassObject*)lpISAMTableList->pTblList->GetNext(lpISAMTableList->iIndex);
}
else
{
lpISAMTableList->lpISAM->errcode = ISAM_EOF;
return ISAM_EOF;
}
}
//Now we have the class definition object
//for the next table let us get table name
SWORD sc = S_OK; // ISAMGetNextTableName2(pSingleTable, fSyncMode, lpISAMTableList,lpTableName);
//Because of stack overflow problems I have moved the
//ISAMGetNextTableName2 code here
BOOL fMatchingPattern = FALSE;
do
{
//Now we have the class definition object
//The table name is held in the property attribute __CLASS
VARIANT grVariant;
BSTR classBSTR = SysAllocString(WBEMDR32_L_CLASS);
if (FAILED(pSingleTable->Get(classBSTR, 0, &grVariant, NULL, NULL)))
{
lpISAMTableList->lpISAM->errcode = ISAM_TABLENAMEFAIL;
SysFreeString(classBSTR);
sc = ISAM_TABLENAMEFAIL;
}
else
{
SysFreeString(classBSTR);
/* Does this filename match the pattern? */
char pBuffer [MAX_TABLE_NAME_LENGTH+1];
pBuffer[0] = 0;
wcstombs(pBuffer, grVariant.bstrVal, MAX_TABLE_NAME_LENGTH);
pBuffer[MAX_TABLE_NAME_LENGTH] = 0;
//Also do not add any class which starts with __ to table list
//If you don't want SYSTEM TABLES
if ( !PatternMatch(TRUE, (LPUSTR) pBuffer, SQL_NTS,
(LPUSTR)lpISAMTableList->lpPattern, lpISAMTableList->cbPattern,
ISAMCaseSensitive(lpISAMTableList->lpISAM)) || (!(lpISAMTableList->fWantSysTables) && !_strnicmp("__", pBuffer, 2)) )
{
/* No. Get the next one */
VariantClear(&grVariant);
//Get the next table here
if (lpISAMTableList->iIndex)
{
if (fReleaseSingleTable)
pSingleTable->Release();
pSingleTable = NULL;
fReleaseSingleTable = FALSE;
pSingleTable = (IWbemClassObject*)lpISAMTableList->pTblList->GetNext(lpISAMTableList->iIndex);
}
else
{
lpISAMTableList->lpISAM->errcode = ISAM_EOF;
return ISAM_EOF;
}
}
else
{
/* Return the name found */
lpTableName[0] = 0;
//RAID 42256
char* pTemp = (char*) lpTableName;
_bstr_t myValue((BSTR)grVariant.bstrVal);
Utility_WideCharToDBCS(myValue, &pTemp, MAX_TABLE_NAME_LENGTH);
lpTableName[MAX_TABLE_NAME_LENGTH] = 0;
VariantClear(&grVariant);
fMatchingPattern = TRUE; //to break out of loop
sc = NO_ISAM_ERR;
}
}
} while (!fMatchingPattern);
//Setup table type, either SYSTEM TABLE or TABLE
if (sc == NO_ISAM_ERR)
{
lpTableType[0] = 0;
if (lpTableName && strlen((LPSTR)lpTableName) && (_strnicmp("__", (LPSTR)lpTableName, 2) == 0))
{
s_lstrcpy(lpTableType, "SYSTEM TABLE");
}
else
{
s_lstrcpy(lpTableType, "TABLE");
}
}
//We have finished with interfaces
//so release them
if (fReleaseSingleTable)
pSingleTable->Release();
return sc;
}
/***************************************************************************/
/* Retrieves next qualifier name from qualifier list */
SWORD INTFUNC ISAMGetNextQualifierName(UDWORD fSyncMode, LPISAMQUALIFIERLIST lpISAMQualifierList,
LPUSTR lpQualifierName)
{
//Initialize, no errors found yet
lpISAMQualifierList->lpISAM->errcode = NO_ISAM_ERR;
//We need to get the next qualifier in the list from the LPISAMQUALIFIERLIST
//However, if this is the first time this function is called, no qualifier list
//will be present, and we will need to get it
// First time through?
if (lpISAMQualifierList->fFirstTime)
{
//Initialize
lpISAMQualifierList->iIndex = NULL;
lpISAMQualifierList->fFirstTime = FALSE;
//Get list of qualifiers from the
//Gateway Server, this maps to getting a list
//of namespaces. However, this list is already held in the
//ISAM structure, so we simply extract from there
//All we need to do is setup the correct position within the list
//Setup first position in qualifier list
lpISAMQualifierList->iIndex = lpISAMQualifierList->lpISAM->pNamespaceMap->GetStartPosition();
}
//Get the next qualifier (namespace)
return ISAMGetNextQualifierName2(lpISAMQualifierList, lpQualifierName);
}
/***************************************************************************/
/* This is the second phase of getting the next qualifier name */
/* This function is called when we have got all the information back */
/* from the MO Server */
SWORD INTFUNC ISAMGetNextQualifierName2(LPISAMQUALIFIERLIST lpISAMQualifierList, LPUSTR lpQualifierName)
{
//Now we have the namespace list, we need to get the 'iIndex' item for the next qualifier
//If the 'iIndex' item is NULL we have reached the end of the list
CString key;
CNamespace* pN;
CString pStr;
if (lpISAMQualifierList->iIndex)
{
lpISAMQualifierList->lpISAM->pNamespaceMap->GetNextAssoc(lpISAMQualifierList->iIndex, key, (CObject* &)pN);
pStr = pN->GetName();
}
else
{
lpISAMQualifierList->lpISAM->errcode = ISAM_EOF;
return ISAM_EOF;
}
//Return Qualifier name
lpQualifierName[0] = 0;
s_lstrcpy (lpQualifierName, pStr);
return NO_ISAM_ERR;
}
/***************************************************************************/
/* Frees the table list stored in the LPISAMTABLELIST structure */
SWORD INTFUNC ISAMFreeTableList(LPISAMTABLELIST lpISAMTableList)
{
lpISAMTableList->lpISAM->errcode = NO_ISAM_ERR;
if (lpISAMTableList->pTblList)
{
if (lpISAMTableList->pTblList->GetCount())
{
POSITION thePos = NULL;
for ( thePos = lpISAMTableList->pTblList->GetHeadPosition(); thePos != NULL; )
{
IWbemClassObject* pTheValue = (IWbemClassObject*) lpISAMTableList->pTblList->GetNext(thePos);
pTheValue->Release();
}
lpISAMTableList->pTblList->RemoveAll();
}
delete lpISAMTableList->pTblList;
lpISAMTableList->pTblList = NULL;
}
if (lpISAMTableList->pGateway2)
{
delete lpISAMTableList->pGateway2;
lpISAMTableList->pGateway2 = NULL;
}
GlobalUnlock (GlobalPtrHandle(lpISAMTableList));
GlobalFree (GlobalPtrHandle(lpISAMTableList));
return NO_ISAM_ERR;
}
/***************************************************************************/
/* Frees the qualifier list stored in the LPISAMQUALIFIERLIST structure */
SWORD INTFUNC ISAMFreeQualifierList(LPISAMQUALIFIERLIST lpISAMQualifierList)
{
lpISAMQualifierList->lpISAM->errcode = NO_ISAM_ERR;
//Initialize
lpISAMQualifierList->iIndex = NULL;
GlobalUnlock (GlobalPtrHandle(lpISAMQualifierList));
GlobalFree (GlobalPtrHandle(lpISAMQualifierList));
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMForeignKey(LPISAM lpISAM, LPUSTR lpszPrimaryKeyTableName,
LPUSTR lpszForeignKeyTableName, LPUSTR lpPrimaryKeyName,
LPUSTR lpForeignKeyName, SWORD FAR *lpfUpdateRule,
SWORD FAR *lpfDeleteRule, UWORD FAR *lpcISAMKeyColumnList,
LPISAMKEYCOLUMNNAME ISAMPrimaryKeyColumnList,
LPISAMKEYCOLUMNNAME ISAMForeignKeyColumnList)
{
/* Never any foreign keys */
return ISAM_EOF;
}
/***************************************************************************/
SWORD INTFUNC ISAMCreateTable(LPISAM lpISAM, LPUSTR lpszTableName,
LPISAMTABLEDEF FAR *lplpISAMTableDef)
{
return ISAM_NOTSUPPORTED;
}
/***************************************************************************/
SWORD INTFUNC ISAMAddColumn(LPISAMTABLEDEF lpISAMTableDef, LPUSTR lpszColumnName,
UWORD iSqlType, UDWORD udParam1, UDWORD udParam2)
{
return ISAM_NOTSUPPORTED;
}
/***************************************************************************/
SWORD INTFUNC ISAMCreateIndex(LPISAMTABLEDEF lpISAMTableDef,
LPUSTR lpszIndexName, BOOL fUnique, UWORD count,
UWORD FAR *icol, BOOL FAR *fDescending)
{
return ISAM_NOTSUPPORTED;
}
/***************************************************************************/
SWORD INTFUNC ISAMDeleteIndex(LPISAM lpISAM, LPUSTR lpszIndexName)
{
return ISAM_NOTSUPPORTED;
}
/***************************************************************************/
/* Opens a specific table and produces a table definition to clearly define the table structure */
// Checked for SetInterfaceSecurityEx on IWbemServices
SWORD INTFUNC ISAMOpenTable(LPISAM lpISAM, LPUSTR szTableQualifier, SWORD cbTableQualifier,
LPUSTR lpszTableName, BOOL fReadOnly,
LPISAMTABLEDEF FAR *lplpISAMTableDef, LPSTMT lpstmt)
{
HGLOBAL h;
LPISAMTABLEDEF lpISAMTableDef;
LPDBASEFILE lpFile;
/* Opening the passthrough SQL result set? */
lpISAM->errcode = NO_ISAM_ERR;
//Create a pointer to store table class definition
//the class definition object will be CREATED on the HEAP
//by the GetClass function or left a NULL pointer
IWbemClassObject* pSingleTable = NULL;
//Allocate memory for DBASEFILE
h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (DBASEFILE));
if (h == NULL || (lpFile = (LPDBASEFILE) GlobalLock (h)) == NULL)
{
if (h)
GlobalFree(h);
lpISAM->errcode = ISAM_MEMALLOCFAIL;
return ISAM_MEMALLOCFAIL;
}
//Allocate memory for TABLEDEF
h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (ISAMTABLEDEF));
if (h == NULL || (lpISAMTableDef = (LPISAMTABLEDEF) GlobalLock (h)) == NULL)
{
if (h)
GlobalFree(h);
if (lpFile)
{
GlobalUnlock(GlobalPtrHandle(lpFile));
GlobalFree(GlobalPtrHandle(lpFile));
lpFile = NULL;
}
lpISAM->errcode = ISAM_MEMALLOCFAIL;
return ISAM_MEMALLOCFAIL;
}
//Initialize
lpFile->tempEnum = new CSafeIEnumWbemClassObject();
lpISAMTableDef->pGateway2 = new CSafeWbemServices();
lpISAMTableDef->pBStrTableName = NULL;
lpISAMTableDef->pSingleTable = NULL;
lpISAMTableDef->pColumnInfo = NULL;
lpISAMTableDef->passthroughMap = NULL;
lpISAMTableDef->firstPassthrInst = NULL;
lpISAMTableDef->virtualInstances = new VirtualInstanceManager();
//Check if PassthroughSQL
BOOL fIsPassthroughSQL = FALSE;
char* virTbl = WBEMDR32_VIRTUAL_TABLE2;
if (lpstmt && (s_lstrcmp(lpszTableName, virTbl) == 0))
{
fIsPassthroughSQL = TRUE;
}
lpISAMTableDef->fIsPassthroughSQL = fIsPassthroughSQL;
// if (s_lstrcmpi(lpszTableName, WBEMDR32_VIRTUAL_TABLE))
{
//Ignore below statement
/* NO, not passthough */
//First get the Gateway Interface
//remember to Release it after use
if (fIsPassthroughSQL)
{
lpISAMTableDef->pGateway2->Transfer(*(lpstmt->lpISAMStatement->pProv));
lpISAMTableDef->passthroughMap = lpstmt->lpISAMStatement->passthroughMap;
lpstmt->lpISAMStatement->passthroughMap = NULL;
lpISAMTableDef->firstPassthrInst= lpstmt->lpISAMStatement->firstPassthrInst;
lpstmt->lpISAMStatement->firstPassthrInst = NULL;
}
else
{
lpISAMTableDef->pGateway2->SetInterfacePtr( lpISAM, szTableQualifier, cbTableQualifier);
}
//Check if a valid interface was returned
if ( ! lpISAMTableDef->pGateway2->IsValid() )
{
//Could not create a Gateway Interface, return error
if (lpFile)
{
if (lpFile->tempEnum)
{
delete lpFile->tempEnum;
lpFile->tempEnum = NULL;
}
GlobalUnlock(GlobalPtrHandle(lpFile));
GlobalFree(GlobalPtrHandle(lpFile));
lpFile = NULL;
}
if (lpISAMTableDef->virtualInstances)
{
delete (lpISAMTableDef->virtualInstances);
lpISAMTableDef->virtualInstances = NULL;
}
if (lpISAMTableDef->pBStrTableName)
{
delete lpISAMTableDef->pBStrTableName;
lpISAMTableDef->pBStrTableName = NULL;
}
if (lpISAMTableDef->pGateway2)
{
delete lpISAMTableDef->pGateway2;
lpISAMTableDef->pGateway2 = NULL;
}
if (lpISAMTableDef)
{
GlobalUnlock(GlobalPtrHandle(lpISAMTableDef));
GlobalFree(GlobalPtrHandle(lpISAMTableDef));
lpISAMTableDef = NULL;
}
lpISAM->errcode = ISAM_PROVIDERFAIL;
return ISAM_PROVIDERFAIL;
}
lpISAMTableDef->pBStrTableName = new CBString();
lpISAMTableDef->pBStrTableName->AddString((LPSTR)lpszTableName, FALSE);
//Get the class definition
if (fIsPassthroughSQL)
{
//Get class definition from lpstmt
pSingleTable = lpstmt->lpISAMStatement->classDef;
lpstmt->lpISAMStatement->classDef = NULL;
}
else
{
IWbemServicesPtr myServicesPtr = NULL;
ISAMGetIWbemServices(lpISAM, *(lpISAMTableDef->pGateway2), myServicesPtr);
if ( FAILED(myServicesPtr->GetObject(lpISAMTableDef->pBStrTableName->GetString(), 0, lpISAMTableDef->pContext, &pSingleTable, NULL)) )
{
//Failed to get named class definition
if (lpFile)
{
if (lpFile->tempEnum)
{
delete lpFile->tempEnum;
lpFile->tempEnum = NULL;
}
GlobalUnlock(GlobalPtrHandle(lpFile));
GlobalFree(GlobalPtrHandle(lpFile));
lpFile = NULL;
}
if (lpISAMTableDef->virtualInstances)
{
delete (lpISAMTableDef->virtualInstances);
lpISAMTableDef->virtualInstances = NULL;
}
if (lpISAMTableDef->pBStrTableName)
{
delete lpISAMTableDef->pBStrTableName;
lpISAMTableDef->pBStrTableName = NULL;
}
if (lpISAMTableDef->pGateway2)
{
delete lpISAMTableDef->pGateway2;
lpISAMTableDef->pGateway2 = NULL;
}
if (lpISAMTableDef)
{
GlobalUnlock(GlobalPtrHandle(lpISAMTableDef));
GlobalFree(GlobalPtrHandle(lpISAMTableDef));
lpISAMTableDef = NULL;
}
lpISAM->errcode = ISAM_TABLEFAIL;
return ISAM_TABLEFAIL;
}
}
}
/* Fill in table definition */
lpISAMTableDef->szTableName[0] = 0;
s_lstrcpy(lpISAMTableDef->szTableName, lpszTableName);
s_lstrcpy(lpISAMTableDef->szPrimaryKeyName, "");
lpISAMTableDef->lpISAM = lpISAM;
lpISAMTableDef->lpFile = lpFile;
lpISAMTableDef->fFirstRead = TRUE;
lpISAMTableDef->iRecord = -1;
if (lpFile)
{
lpISAMTableDef->lpFile->sortArray = NULL;
if (fIsPassthroughSQL)
{
lpISAMTableDef->lpFile->pAllRecords = new CMapWordToPtr();
lpISAMTableDef->lpFile->fMoreToCome = TRUE; //more instances need to be fetched (none fetched so far)
if (lpISAMTableDef->lpFile->tempEnum)
delete (lpISAMTableDef->lpFile->tempEnum);
lpISAMTableDef->lpFile->tempEnum = lpstmt->lpISAMStatement->tempEnum;
lpstmt->lpISAMStatement->tempEnum = NULL; //SAI NEW to avoid enumeration being deleted in ISAMFreeStatement
}
else
{
lpISAMTableDef->lpFile->pAllRecords = new CMapWordToPtr();
delete lpISAMTableDef->lpFile->tempEnum;
lpISAMTableDef->lpFile->tempEnum = new CSafeIEnumWbemClassObject();
lpISAMTableDef->lpFile->fMoreToCome = FALSE; //not used but set it with a value anyway
}
lpISAMTableDef->lpFile->record = NULL;
}
lpISAMTableDef->netISAMTableDef = NET_OPAQUE_INVALID;
lpISAMTableDef->hPreFetchedValues = NULL;
lpISAMTableDef->cbBookmark = 0;
lpISAMTableDef->bookmark.currentRecord = 0;
lpISAMTableDef->bookmark.currentInstance = 0;
//this is 8 - see assinment above
lpISAMTableDef->pSingleTable = pSingleTable; //Contains class info
//We must indicate to the class below how to parse the information
//Ther unique case is when we do passthrough for multi-tables
//and we get a __Generic class
//We check for this
BOOL fIs__Generic = FALSE;
if (fIsPassthroughSQL)
{
//Extract class name from class definition
//The table name is held in the property attribute __CLASS
VARIANT grVariant;
BSTR classBSTR = SysAllocString(WBEMDR32_L_CLASS);
if (FAILED(pSingleTable->Get(classBSTR, 0, &grVariant, NULL, NULL)))
{
//SAI ADDED - Failed should we also
//free pSingleTable ?
lpISAM->errcode = ISAM_NOTSUPPORTED;
SysFreeString(classBSTR);
if (lpFile)
{
if (lpFile->tempEnum)
{
delete lpFile->tempEnum;
lpFile->tempEnum = NULL;
}
GlobalUnlock(GlobalPtrHandle(lpFile));
GlobalFree(GlobalPtrHandle(lpFile));
lpFile = NULL;
}
if (lpISAMTableDef->virtualInstances)
{
delete (lpISAMTableDef->virtualInstances);
lpISAMTableDef->virtualInstances = NULL;
}
if (lpISAMTableDef->pBStrTableName)
{
delete lpISAMTableDef->pBStrTableName;
lpISAMTableDef->pBStrTableName = NULL;
}
if (lpISAMTableDef->pGateway2)
{
delete lpISAMTableDef->pGateway2;
lpISAMTableDef->pGateway2 = NULL;
}
if (lpISAMTableDef->pSingleTable)
{
lpISAMTableDef->pSingleTable->Release();
lpISAMTableDef->pSingleTable = NULL;
}
if (lpISAMTableDef)
{
GlobalUnlock(GlobalPtrHandle(lpISAMTableDef));
GlobalFree(GlobalPtrHandle(lpISAMTableDef));
lpISAMTableDef = NULL;
}
return ISAM_NOTSUPPORTED;
}
SysFreeString(classBSTR);
//Compare with __Generic
if (_wcsicmp(grVariant.bstrVal, L"__Generic") == 0)
{
fIs__Generic = TRUE;
}
}
lpISAMTableDef->fIs__Generic = fIs__Generic;
ClassColumnInfoBase* tempInfo = new ClassColumnInfoBase(lpISAMTableDef,lpISAMTableDef->fIs__Generic);
lpISAMTableDef->pColumnInfo = tempInfo;
//DCR 29279
//Add LocaleID context object
lpISAMTableDef->pContext = NULL;
ISAMAddLocaleIDContextObject(lpISAMTableDef, lpISAMTableDef->lpISAM);
*lplpISAMTableDef = lpISAMTableDef;
return NO_ISAM_ERR;
}
IWbemContext* ISAMCreateLocaleIDContextObject(char* lpLocale)
{
IWbemContext* pContext = NULL;
if (!lpLocale)
return NULL;
if (!lstrlen(lpLocale))
return NULL;
//First get the context interface
//===============================
SCODE sc = CoCreateInstance(CLSID_WbemContext, NULL, CLSCTX_INPROC_SERVER , IID_IWbemContext, (void**) ( &pContext ) );
if ( FAILED(sc) )
{
ODBCTRACE("WBEM ODBC DRIVER : Failed to create context object for LocaleId");
return NULL;
}
//Now add the locale value
_bstr_t myLocaleParm ("LocaleID");
_variant_t myLocaleVal(lpLocale);
sc = pContext->SetValue(myLocaleParm, 0, &myLocaleVal);
if ( FAILED(sc) )
{
ODBCTRACE("WBEM ODBC DRIVER : Failed to set LocaleId in context object");
return NULL;
}
return pContext;
}
void ISAMAddLocaleIDContextObject(LPISAMTABLEDEF lpISAMTableDef, LPISAM lpISAM)
{
//add locale id to context object
lpISAMTableDef->pContext = ISAMCreateLocaleIDContextObject(lpISAM->m_Locale);
}
/***************************************************************************/
SWORD INTFUNC ISAMRewind(LPISAMTABLEDEF lpISAMTableDef)
{
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
lpISAMTableDef->fFirstRead = TRUE;
lpISAMTableDef->iRecord = -1;
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMSort(LPISAMTABLEDEF lpISAMTableDef,
UWORD count,
UWORD FAR * icol,
BOOL FAR * fDescending)
{
if (count)
{
lpISAMTableDef->lpISAM->errcode = ISAM_NOTSUPPORTED;
return ISAM_NOTSUPPORTED;
}
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMRestrict(LPISAMTABLEDEF lpISAMTableDef,
UWORD count,
UWORD FAR * icol,
UWORD FAR * fOperator,
SWORD FAR * fCType,
PTR FAR * rgbValue,
SDWORD FAR * cbValue)
{
/* Note: Indexes are not used in this implementation, so this */
/* restriction is ignored. */
lpISAMTableDef->lpISAM->errcode = ISAM_NOTSUPPORTED;
return ISAM_NOTSUPPORTED;
}
// Checked for SetInterfaceSecurityEx on IWbemServices
void ISAMPatchUpGatewaySecurity(LPISAM lpISAM, IWbemServices* myServicesPtr)
{
SCODE sc = GetAuthImp( myServicesPtr, &(lpISAM->dwAuthLevel), &(lpISAM->dwImpLevel));
if(sc == S_OK)
{
if (lpISAM->dwAuthLevel > RPC_C_AUTHN_LEVEL_NONE)
lpISAM->dwImpLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
// CBString myServerStr;
// myServerStr.AddString( (LPSTR)lpISAM->szServer, FALSE );
// CServerLocationCheck myCheck (myServerStr);
BOOL fIsLocalConnection = lpISAM->fIsLocalConnection;//myCheck.IsLocal();
sc = ISAMSetCloaking2(myServicesPtr,
fIsLocalConnection,
lpISAM->fW2KOrMore,
lpISAM->dwAuthLevel,
lpISAM->dwImpLevel,
lpISAM->gpAuthIdentity);
/*
if ( fIsLocalConnection && (lpISAM->fW2KOrMore) )
{
sc = WbemSetDynamicCloaking(myServicesPtr, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
}
else
{
sc = SetInterfaceSecurityEx(myServicesPtr, lpISAM->gpAuthIdentity, gpPrincipal, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
}
*/
}
}
/***************************************************************************/
#define WBEMDR32_ELEMENTS_TO_READ 1000
/* retrieves the next record from the selected table */
// Checked for SetInterfaceSecurityEx on IWbemServices and IEnumWbemClassObject
SWORD INTFUNC ISAMNextRecord(LPISAMTABLEDEF lpISAMTableDef, LPSTMT lpstmt)
{
ODBCTRACE("\nWBEM ODBC Driver : ISAMNextRecord\n");
SWORD err = DBASE_ERR_SUCCESS;
// Move to the next record
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
if (lpISAMTableDef->lpFile != NULL)
{
if (lpISAMTableDef->fFirstRead)
{
//copy table name
char pTableName [MAX_TABLE_NAME_LENGTH+1];
pTableName[0] = 0;
wcstombs(pTableName, lpISAMTableDef->pBStrTableName->GetString(), MAX_TABLE_NAME_LENGTH);
pTableName[MAX_TABLE_NAME_LENGTH] = 0;
//Get enumeration of all instances of current class
//First check if this table has been RESET
SCODE sc;
if (lpISAMTableDef->lpFile->tempEnum->IsValid())
{
//Yes, reuse old enumeration
//Passthrough SQL will always go here !!!
sc = S_OK;
}
else
{
//no old enumeration, so create one
lpISAMTableDef->lpFile->tempEnum->Invalidate();
//before getting enumeration check if we can perform
//some optimization by converting to an WBEM Level 1 query
//base on a single table
LPSQLNODE lpRootNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
LPSQLNODE lpSqlNode2 = ToNode(lpstmt->lpSqlStmt, lpRootNode->node.root.sql);
char* buffer = NULL;
BOOL fOptimization = FALSE;
//Check if WBEM Level 1 optimization is enabled
if (lpISAMTableDef->lpISAM->fOptimization)
{
if ( lpSqlNode2->node.select.Predicate != NO_SQLNODE)
{
LPSQLNODE lpPredicateNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode2->node.select.Predicate);
PredicateParser theParser (&lpRootNode, lpISAMTableDef);
theParser.GeneratePredicateString(lpPredicateNode, &buffer);
}
}
//Sai Wong
// if (buffer && lstrlen(buffer))
{
//Get select list
char* selectStr = NULL;
TableColumnInfo selectInfo (&lpRootNode, &lpSqlNode2);
lpISAMTableDef->passthroughMap = NULL;
selectInfo.BuildSelectList(lpISAMTableDef, &selectStr, TRUE, &(lpISAMTableDef->passthroughMap));
if (selectStr)
{
fOptimization = TRUE;
_bstr_t sqltextBSTR = L"SELECT ";
_bstr_t sqltextBSTR2;
sqltextBSTR += selectStr;
sqltextBSTR += L" FROM ";
sqltextBSTR += pTableName;
//Is there a WHERE statement ?
if (buffer && lstrlen(buffer))
{
//RAID 29811
//If this query contains a JOIN do not add in the WHERE predicate
//so we do the ON and WHERE in the correct order
//Get the table list first to find out if we are
//SQL-89 or SQL-92
char* checkTableList = NULL;
BOOL fIsSQL89 = TRUE;
selectInfo.BuildTableList(&checkTableList, fIsSQL89);
delete checkTableList;
if (fIsSQL89)
{
sqltextBSTR2 = sqltextBSTR; //make copy of this
sqltextBSTR += L" WHERE ";
sqltextBSTR += buffer;
}
}
sc = lpISAMTableDef->lpFile->tempEnum->SetInterfacePtr(lpISAMTableDef->lpISAM, WMI_EXEC_QUERY, sqltextBSTR, lpISAMTableDef->pGateway2);
ODBCTRACE(_T("\nWBEM ODBC Driver : Non-passthrough WQL = "));
ODBCTRACE(sqltextBSTR);
ODBCTRACE(_T("\n"));
CString sMessage;
sMessage.Format(_T("\nWBEM ODBC Driver : sc = %ld\n"), sc);
ODBCTRACE(sMessage);
sMessage.Format(_T("\nWBEM ODBC Driver : LPISAM data : szUser = %s\nszPassword = %s\nszDatabase = %s\nszServer = %s\n"),
lpISAMTableDef->lpISAM->szUser,
lpISAMTableDef->lpISAM->szPassword,
lpISAMTableDef->lpISAM->szDatabase,
lpISAMTableDef->lpISAM->szServer
);
ODBCTRACE(sMessage);
if (! lpISAMTableDef->pGateway2->IsValid() )
ODBCTRACE( _T("\nWBEM ODBC Driver :pGateway is NULL\n"));
//If ExecQuery is not supported or if there is any problems, get all entries as normal
if ( (sc == WBEM_E_NOT_SUPPORTED) || (sc == WBEM_E_FAILED) || (sc == WBEM_E_INVALID_QUERY) )
{
//Try it without the LIKE predicate
if ( sqltextBSTR2.length() )
{
if (lpISAMTableDef->lpISAM->fOptimization)
{
if ( lpSqlNode2->node.select.Predicate != NO_SQLNODE)
{
if (buffer)
delete buffer;
buffer = NULL;
LPSQLNODE lpPredicateNode = ToNode(lpstmt->lpSqlStmt, lpSqlNode2->node.select.Predicate);
PredicateParser theParser (&lpRootNode, lpISAMTableDef, FALSE);
theParser.GeneratePredicateString(lpPredicateNode, &buffer);
if ( buffer && lstrlen(buffer) )
{
sqltextBSTR2 += L" WHERE ";
sqltextBSTR2 += buffer;
}
ODBCTRACE(_T("\nWBEM ODBC Driver : Non-passthrough WQL (attempt 2) = "));
ODBCTRACE(sqltextBSTR2);
ODBCTRACE(_T("\n"));
sc = lpISAMTableDef->lpFile->tempEnum->SetInterfacePtr(lpISAMTableDef->lpISAM, WMI_EXEC_QUERY, sqltextBSTR, lpISAMTableDef->pGateway2);
//If ExecQuery is not supported or if there is any problems, get all entries as normal
if ( (sc == WBEM_E_NOT_SUPPORTED) || (sc == WBEM_E_FAILED) || (sc == WBEM_E_INVALID_QUERY) )
{
fOptimization = FALSE;
}
}
}
}
else
{
fOptimization = FALSE;
}
}
delete selectStr;
}
}
if (!fOptimization)
{
//no optimization allowed
ODBCTRACE(_T("\nWBEM ODBC Driver : Non-passthrough WQL failed performing CreateInstanceEnum\n"));
sc = lpISAMTableDef->lpFile->tempEnum->SetInterfacePtr(lpISAMTableDef->lpISAM, WMI_CREATE_INST_ENUM, lpISAMTableDef->pBStrTableName->GetString(), lpISAMTableDef->pGateway2);
}
//Tidy up
if (buffer)
delete buffer;
}
if ( sc != S_OK )
{
err = DBASE_ERR_NODATAFOUND;
}
else
{
if (lpISAMTableDef->lpFile->tempEnum->IsValid())
{
IWbemServicesPtr myServicesPtr = NULL;
ISAMGetIWbemServices(lpISAMTableDef->lpISAM, *(lpISAMTableDef->pGateway2), myServicesPtr);
IEnumWbemClassObjectPtr myIEnumWbemClassObject = NULL;
lpISAMTableDef->lpFile->tempEnum->GetInterfacePtr(myIEnumWbemClassObject);
// CBString myServerStr;
// myServerStr.AddString( (LPSTR)lpISAMTableDef->lpISAM->szServer, FALSE );
// CServerLocationCheck myCheck (myServerStr);
BOOL fIsLocalConnection = lpISAMTableDef->lpISAM->fIsLocalConnection;//myCheck.IsLocal();
ISAMSetCloaking2(myIEnumWbemClassObject,
fIsLocalConnection,
lpISAMTableDef->lpISAM->fW2KOrMore,
lpISAMTableDef->lpISAM->dwAuthLevel,
lpISAMTableDef->lpISAM->dwImpLevel,
lpISAMTableDef->lpISAM->gpAuthIdentity);
/*
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(myIEnumWbemClassObject, lpISAMTableDef->lpISAM->dwAuthLevel, lpISAMTableDef->lpISAM->dwImpLevel);
}
else
{
SetInterfaceSecurityEx(myIEnumWbemClassObject,
lpISAMTableDef->lpISAM->gpAuthIdentity,
gpPrincipal,
lpISAMTableDef->lpISAM->dwAuthLevel,
lpISAMTableDef->lpISAM->dwImpLevel);
}
*/
//Reset to beginning of list
myIEnumWbemClassObject->Reset();
//Read in ALL records (if not already read)
//but only for non-passthrough SQL case
//if this is passthrough SQL delay retrieval
if (
(!lpISAMTableDef->fIsPassthroughSQL) &&
(lpISAMTableDef->lpFile->pAllRecords->IsEmpty())
)
{
WORD fElements2Read = WBEMDR32_ELEMENTS_TO_READ;
ULONG puReturned = 0;
IWbemClassObject* myRecords [WBEMDR32_ELEMENTS_TO_READ];
//Initialize array
for (ULONG loop = 0; loop < fElements2Read; loop++)
{
myRecords[loop] = NULL; //reset for next instance
}
WORD elementNumber = 0;
while ( myIEnumWbemClassObject->Next(-1, fElements2Read, myRecords, &puReturned) == S_OK )
{
for (loop = 0; loop < puReturned; loop++)
{
lpISAMTableDef->lpFile->pAllRecords->SetAt(elementNumber++, (void*)myRecords[loop] );
myRecords[loop] = NULL; //reset for next instance
}
puReturned = 0;
}
//This could be the last time around the loop
if (puReturned)
{
for (ULONG loop = 0; loop < puReturned; loop++)
{
lpISAMTableDef->lpFile->pAllRecords->SetAt(elementNumber++, (void*)myRecords[loop] );
}
}
}
//Setup bookmark
lpISAMTableDef->lpFile->currentRecord = 0;
}
else
{
err = DBASE_ERR_NODATAFOUND;
}
}
}
if (err != DBASE_ERR_NODATAFOUND)
{
//Now fetch the next record
//Check Virtual Instances
//they occur if you query for array type columns which map
//to multiple instances
BOOL fFetchNextInstance = TRUE;
if ( lpISAMTableDef->virtualInstances )
{
long numInst = lpISAMTableDef->virtualInstances->cNumberOfInstances;
long currInst = lpISAMTableDef->virtualInstances->currentInstance;
CString myText;
myText.Format("\nWBEM ODBC Driver : number of virtual instances = %ld current virtual instance = %ld\n", numInst, currInst);
ODBCTRACE(myText);
if ( (numInst != 0) && ( (currInst + 1) < numInst ) )
{
//Don't fetch another instance
//just increment virtual instance
ODBCTRACE ("\nWBEM ODBC Driver : not fetching another instance, just updating virtual instance number\n");
fFetchNextInstance = FALSE;
++(lpISAMTableDef->virtualInstances->currentInstance);
}
}
if (fFetchNextInstance)
{
//In passthrough SQL case you might not have any instances yet
//or we might have read all the 10 instances and need to load the next batch,
//therefore we make a check now
if ( lpISAMTableDef->fIsPassthroughSQL )
{
//Do we need to load in the next batch of 10 instances ?
if (
(
lpISAMTableDef->lpFile->pAllRecords->IsEmpty() ||
lpISAMTableDef->lpFile->currentRecord >= BATCH_NUM_OF_INSTANCES
)
&& lpISAMTableDef->lpFile->fMoreToCome )
{
//Yes, load next batch
ODBCTRACE ("\nWBEM ODBC Driver : Need to Load next batch of 10 instances\n");
//First clear out old instances, if applicable
if (! lpISAMTableDef->lpFile->pAllRecords->IsEmpty() )
{
for(POSITION pos = lpISAMTableDef->lpFile->pAllRecords->GetStartPosition(); pos != NULL; )
{
WORD key = 0;
IWbemClassObject* pa = NULL;
lpISAMTableDef->lpFile->pAllRecords->GetNextAssoc( pos, key, (void*&)pa );
if (pa)
{
pa->Release();
}
}
delete (lpISAMTableDef->lpFile->pAllRecords);
lpISAMTableDef->lpFile->pAllRecords = new CMapWordToPtr();
}
//Load the next 10 instances
lpISAMTableDef->lpFile->currentRecord = 0;
WORD fElements2Read = BATCH_NUM_OF_INSTANCES;
ULONG puReturned = 0;
IWbemClassObject* myRecords [BATCH_NUM_OF_INSTANCES];
//Initialize array
for (ULONG loop = 0; loop < fElements2Read; loop++)
{
myRecords[loop] = NULL; //reset for next instance
}
WORD elementNumber = 0;
//Special case. The 1st SQL passthrough instance was
//already fetched
BOOL fSpecialCase = FALSE;
if (lpISAMTableDef->firstPassthrInst)
{
fSpecialCase = TRUE;
lpISAMTableDef->lpFile->pAllRecords->SetAt(elementNumber++, (void*)lpISAMTableDef->firstPassthrInst);
lpISAMTableDef->firstPassthrInst = NULL; //mark as used
}
ODBCTRACE("\nWBEM ODBC Driver : Calling Next(...)\n");
IEnumWbemClassObjectPtr myIEnumWbemClassObject = NULL;
lpISAMTableDef->lpFile->tempEnum->GetInterfacePtr(myIEnumWbemClassObject); // Note: don't need to call SetInterfaceSecurityEx because it has already been called for this ptr
// CBString myServerStr;
// myServerStr.AddString( (LPSTR)lpISAMTableDef->lpISAM->szServer, FALSE );
// CServerLocationCheck myCheck (myServerStr);
BOOL fIsLocalConnection = lpISAMTableDef->lpISAM->fIsLocalConnection;//myCheck.IsLocal();
if ( fIsLocalConnection && (lpISAMTableDef->lpISAM->fW2KOrMore) )
{
WbemSetDynamicCloaking(myIEnumWbemClassObject, lpISAMTableDef->lpISAM->dwAuthLevel, lpISAMTableDef->lpISAM->dwImpLevel);
}
if (SUCCEEDED(myIEnumWbemClassObject->Next(-1, fElements2Read-(fSpecialCase?1:0), myRecords, &puReturned)))
{
CString myText;
myText.Format("\nWBEM ODBC Driver : We got back a batch of %ld instances\n", puReturned);
ODBCTRACE(myText);
int i = 0;
loop = 0;
for (; i < puReturned; i++)
{
lpISAMTableDef->lpFile->pAllRecords->SetAt(elementNumber++, (void*)myRecords[i] );
loop++;
}
puReturned+=((fSpecialCase?1:0));
//Did we get 10 instances back or less
BOOL fGotFullSetofInstances = TRUE;
fGotFullSetofInstances = (puReturned == BATCH_NUM_OF_INSTANCES) ? TRUE : FALSE;
if ( !fGotFullSetofInstances )
{
//This is the last set of 10 instances
lpISAMTableDef->lpFile->fMoreToCome = FALSE;
}
}
}
}
lpISAMTableDef->lpFile->record = NULL;
ODBCTRACE ("\nWBEM ODBC Driver : Fetching next instance from CMapWordToPtr\n");
BOOL fStatus = lpISAMTableDef->lpFile->pAllRecords->Lookup
((WORD)lpISAMTableDef->lpFile->currentRecord, (void* &)lpISAMTableDef->lpFile->record);
//Check that a record was returned
if (fStatus && lpISAMTableDef->lpFile->record)
{
//Increment bookmark
++(lpISAMTableDef->lpFile->currentRecord);
//Remove previous virtual instance map (if there was one)
delete (lpISAMTableDef->virtualInstances);
lpISAMTableDef->virtualInstances = new VirtualInstanceManager();
lpISAMTableDef->virtualInstances->Load(lpISAMTableDef->passthroughMap, lpISAMTableDef->lpFile->record);
}
else
{
err = DBASE_ERR_NODATAFOUND;
}
}
}
}
else
{
if (lpISAMTableDef->iRecord != 1)
err = DBASE_ERR_SUCCESS;
else
err = DBASE_ERR_NODATAFOUND;
}
// Error if end of file?
if (err == DBASE_ERR_NODATAFOUND)
{
lpISAMTableDef->lpISAM->errcode = ISAM_EOF;
return ISAM_EOF;
}
else if (err != DBASE_ERR_SUCCESS)
{
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
lpISAMTableDef->fFirstRead = FALSE;
return NO_ISAM_ERR;
}
/***************************************************************************/
/* Provides default value for selected column */
SWORD ISAMProvideDefaultValue(SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue)
{
SWORD err = NO_ISAM_ERR;
switch (fCType)
{
case SQL_C_DOUBLE:
{
//Check that you have enough buffer to store value
*pcbValue = sizeof(double);
if (cbValueMax >= *pcbValue)
{
*((double *)rgbValue) = (double)0;
}
else
{
*pcbValue = 0;
err = ISAM_ERROR;
}
}
break;
case SQL_C_DATE:
{
*pcbValue = sizeof (DATE_STRUCT);
DATE_STRUCT FAR* pDateStruct = (DATE_STRUCT FAR*)rgbValue;
if ( cbValueMax >= (*pcbValue) )
{
pDateStruct->year = (SWORD)0;
pDateStruct->month = (UWORD)0;
pDateStruct->day = (UWORD)0;
}
else
{
*pcbValue = 0;
err = ISAM_ERROR;
}
}
break;
case SQL_C_TIME:
{
//Check that you have enough buffer to store value
*pcbValue = sizeof (TIME_STRUCT);
TIME_STRUCT FAR* pTimeStruct = (TIME_STRUCT FAR*)rgbValue;
if ( cbValueMax >= (*pcbValue) )
{
pTimeStruct->hour = (UWORD)0;
pTimeStruct->minute = (UWORD)0;
pTimeStruct->second = (UWORD)0;
}
else
{
*pcbValue = 0;
err = ISAM_ERROR;
}
}
break;
case SQL_C_TIMESTAMP:
{
//Check that you have enough buffer to store value
*pcbValue = sizeof (TIMESTAMP_STRUCT);
TIMESTAMP_STRUCT FAR* pTimeStampStruct = (TIMESTAMP_STRUCT FAR*)rgbValue;
if ( cbValueMax >= (*pcbValue) )
{
pTimeStampStruct->year = (SWORD)0;
pTimeStampStruct->month = (UWORD)0;
pTimeStampStruct->day = (UWORD)0;
pTimeStampStruct->hour = (UWORD)0;
pTimeStampStruct->minute = (UWORD)0;
pTimeStampStruct->second = (UWORD)0;
pTimeStampStruct->fraction = 0;
}
else
{
*pcbValue = 0;
err = ISAM_ERROR;
}
}
break;
case SQL_C_CHAR:
case SQL_C_BINARY:
default:
{
*pcbValue = SQL_NULL_DATA;
}
break;
}
return err;
}
/***************************************************************************/
/* Gets the data value for the selected column */
SWORD INTFUNC ISAMGetData(LPISAMTABLEDEF lpISAMTableDef,
UWORD icol,
SDWORD cbOffset,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue)
{
//This manages the thread locale id
ThreadLocaleIdManager myThreadStuff(lpISAMTableDef->lpISAM);
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
if ((fCType != SQL_CHAR) && (lpISAMTableDef->lpFile == NULL))
{
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 1\n");
return ISAM_ERROR;
}
if (cbValueMax == SQL_NTS)
cbValueMax = s_lstrlen (rgbValue);
//create SAFEARRAY to store BSTR's
SAFEARRAY FAR* rgSafeArray = NULL;
//Create a store for column name
BSTR lpbString;
CBString temppbString;
//Stores table alias
CBString cbTableAlias;
//Check if you have a __Generic class
BOOL fIs__Generic = lpISAMTableDef->fIs__Generic;
//Points to the current instance for the property
IWbemClassObjectPtr theRecord = NULL;
//Points to the current class definition
IWbemClassObjectPtr theClassDefinition = NULL;
if (!fIs__Generic)
{
//Setup the record pointer
theRecord = lpISAMTableDef->lpFile->record;
//Setup the class definition pointer
theClassDefinition = lpISAMTableDef->pSingleTable;
//Fetch name of column "icol"
//Remeber with abstract and derived classes the properities in the class definition
//may be different to the properties in the instances.
//The "icol" maps to a class property,so we get the names from the class
lpISAMTableDef->pSingleTable->GetNames(NULL, 0, NULL, &rgSafeArray);
SafeArrayLock(rgSafeArray);
LONG iColumnNum = (LONG)icol;
if ( FAILED(SafeArrayGetElement(rgSafeArray, &iColumnNum, &lpbString)) )
{
//To be more resilient we specify a default value
//NULL for SQL_C_CHAR and zero for numeric values
SWORD fErr = ISAMProvideDefaultValue(fCType, rgbValue, cbValueMax, pcbValue);
if (fErr != NO_ISAM_ERR)
{
lpISAMTableDef->lpISAM->errcode = fErr;
SafeArrayUnlock(rgSafeArray);
SafeArrayDestroy(rgSafeArray); //SAI ADDED
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 2\n");
return fErr;
}
SafeArrayUnlock(rgSafeArray);
SafeArrayDestroy(rgSafeArray); //SAI ADDED
return NO_ISAM_ERR;
}
#ifdef TESTING
//copy column name
char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
pColumnName[0] = 0;
wcstombs(pColumnName, lpbString, MAX_COLUMN_NAME_LENGTH);
pColumnName[MAX_COLUMN_NAME_LENGTH] = 0;
#endif
}
else
{
//Get the icol from passthrough map
PassthroughLookupTable* passthroughElement = NULL;
WORD myIndex = (WORD)icol;
BOOL status = lpISAMTableDef->passthroughMap->Lookup(myIndex, (void*&)passthroughElement);
if (status)
{
temppbString.AddString(passthroughElement->GetColumnName(), FALSE);
char* lpTableAlias = passthroughElement->GetTableAlias();
cbTableAlias.AddString(lpTableAlias, FALSE);
//Get the embedded object (keyed on table alias)
VARIANT vEmbedded;
if ( SUCCEEDED(lpISAMTableDef->lpFile->record->Get(cbTableAlias.GetString(), 0, &vEmbedded, NULL, NULL)) )
{
IUnknown* myUnk = vEmbedded.punkVal;
myUnk->QueryInterface(IID_IWbemClassObject, (void**)&theRecord);
VariantClear(&vEmbedded);
}
else
{
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 3\n");
return ISAM_ERROR;
}
//Do the same for class definition
VARIANT vClassEmbedded;
if ( SUCCEEDED(lpISAMTableDef->lpFile->record->Get(cbTableAlias.GetString(), 0, &vClassEmbedded, NULL, NULL)) )
{
IUnknown* myUnk = vClassEmbedded.punkVal;
myUnk->QueryInterface(IID_IWbemClassObject, (void**)&theClassDefinition);
VariantClear(&vClassEmbedded);
}
else
{
//(9) Should we release theRecord
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 4\n");
return ISAM_ERROR;
}
}
else
{
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 5\n");
return ISAM_ERROR;
}
}
//Get the value of the column
CIMTYPE wbemType = 0;
SWORD wbemVariantType = 0;
VARIANT vVariantVal;
if ( FAILED(theRecord->Get(fIs__Generic ? temppbString.GetString() : lpbString, 0, &vVariantVal, &wbemType, NULL)) )
{
//To be more resilient we specify a default value
//NULL for SQL_C_CHAR and zero for numeric values
SWORD fErr = ISAMProvideDefaultValue(fCType, rgbValue, cbValueMax, pcbValue);
//Tidy up
if (rgSafeArray)
{
SafeArrayUnlock(rgSafeArray);
SafeArrayDestroy(rgSafeArray);
}
if (fErr != NO_ISAM_ERR)
{
//(9) Should we release theRecord and theClassDefinition
//if __generic ?
lpISAMTableDef->lpISAM->errcode = fErr;
if (!fIs__Generic)
SysFreeString(lpbString);
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 6\n");
return fErr;
}
//(9) Should we release theRecord and theClassDefinition
//if __generic ?
if (!fIs__Generic)
SysFreeString(lpbString);
return NO_ISAM_ERR;
}
//New
//Get attributes for chosen column
IWbemQualifierSetPtr pQualifierSet = NULL;
if ( S_OK != (theClassDefinition->GetPropertyQualifierSet(fIs__Generic ? temppbString.GetString() : lpbString, &pQualifierSet)) )
{
pQualifierSet = NULL;
}
//Tidy up
if (rgSafeArray)
{
SafeArrayUnlock(rgSafeArray);
SafeArrayDestroy(rgSafeArray);
}
//Get CIMTYPE String
VARIANT pVal2;
BSTR syntaxStr = NULL;
BOOL fClearpVal2 = FALSE;
if (pQualifierSet)
{
BSTR cimtypeBSTR = SysAllocString(WBEMDR32_L_CIMTYPE);
SCODE result = pQualifierSet->Get(cimtypeBSTR, 0, &pVal2, 0);
SysFreeString(cimtypeBSTR);
if ( S_OK == result )
{
if (pVal2.bstrVal)
syntaxStr = pVal2.bstrVal;
fClearpVal2 = TRUE;
}
}
//Get MAXLEN Value
VARIANT pVal3;
SDWORD maxLenVal = 0;
if (pQualifierSet)
{
BSTR maxBSTR = SysAllocString(WBEMDR32_L_MAX);
SCODE result = pQualifierSet->Get(maxBSTR, 0, &pVal3, 0);
SysFreeString(maxBSTR);
if ( S_OK == result )
{
maxLenVal = pVal3.iVal;
VariantClear(&pVal3);
}
}
//Get value from variant
ISAMGetWbemVariantType(wbemType, wbemVariantType);
//get the index for this column
long index = -1;
_bstr_t theTableAlias = cbTableAlias.GetString();
_bstr_t theColumnName = fIs__Generic ? temppbString.GetString() : lpbString;
if (lpISAMTableDef->virtualInstances)
{
long theInstance = lpISAMTableDef->virtualInstances->currentInstance;
//Remove previous virtual instance map (if there was one)
delete (lpISAMTableDef->virtualInstances);
lpISAMTableDef->virtualInstances = new VirtualInstanceManager();
lpISAMTableDef->virtualInstances->Load(lpISAMTableDef->passthroughMap, lpISAMTableDef->lpFile->record);
//Restore current instance
lpISAMTableDef->virtualInstances->currentInstance = theInstance;
index = lpISAMTableDef->virtualInstances->GetArrayIndex(theTableAlias, theColumnName, theInstance);
}
if (!fIs__Generic)
SysFreeString(lpbString);
SWORD err = ISAMGetValueFromVariant(vVariantVal, fCType,
rgbValue, cbValueMax, pcbValue, wbemVariantType, syntaxStr, maxLenVal, index);
if (fClearpVal2)
VariantClear(&pVal2);
if (err != NO_ISAM_ERR)
{
lpISAMTableDef->lpISAM->errcode = err;
ODBCTRACE("\nWBEM ODBC Driver : ISAMGetData : Error position 7\n");
return err;
}
VariantClear(&vVariantVal);
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMPutData(LPISAMTABLEDEF lpISAMTableDef,
UWORD icol,
SWORD fCType,
PTR rgbValue,
SDWORD cbValue)
{
/* Not allowed for the passthrough table */
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
if (lpISAMTableDef->lpFile == NULL) {
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
/* Null? */
if (cbValue == SQL_NULL_DATA) {
/* Yes. Set value to NULL */
if (dBaseSetColumnNull(lpISAMTableDef->lpFile, (UWORD) (icol+1)) !=
DBASE_ERR_SUCCESS) {
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
}
else {
/* No. Set the value */
switch (fCType) {
case SQL_C_DOUBLE:
{
UCHAR string[20];
if (DoubleToChar(*((double far *)rgbValue), TRUE, (LPUSTR)string,
sizeof(string)))
string[sizeof(string)-1] = '\0';
if (dBaseSetColumnCharVal(lpISAMTableDef->lpFile, (UWORD) (icol+1),
string, lstrlen((char*)string)) != DBASE_ERR_SUCCESS) {
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
}
break;
case SQL_C_CHAR:
if (cbValue == SQL_NTS)
cbValue = lstrlen((char*)rgbValue);
if (dBaseSetColumnCharVal(lpISAMTableDef->lpFile, (UWORD) (icol+1),
(UCHAR FAR*)rgbValue, cbValue) != DBASE_ERR_SUCCESS) {
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
break;
case SQL_C_DATE:
{
UCHAR string[11];
DateToChar((DATE_STRUCT far *) rgbValue, (LPUSTR)string);
if (dBaseSetColumnCharVal(lpISAMTableDef->lpFile, (UWORD) (icol+1),
string, lstrlen((char*)string)) != DBASE_ERR_SUCCESS) {
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
}
break;
default:
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
}
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMInsertRecord(LPISAMTABLEDEF lpISAMTableDef)
{
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
if (lpISAMTableDef->lpFile == NULL) {
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
if (dBaseAddRecord(lpISAMTableDef->lpFile) != DBASE_ERR_SUCCESS) {
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMUpdateRecord(LPISAMTABLEDEF lpISAMTableDef)
{
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
if (lpISAMTableDef->lpFile == NULL) {
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMDeleteRecord(LPISAMTABLEDEF lpISAMTableDef)
{
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
if (lpISAMTableDef->lpFile == NULL) {
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
if (dBaseDeleteRecord(lpISAMTableDef->lpFile) != DBASE_ERR_SUCCESS) {
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMGetBookmark(LPISAMTABLEDEF lpISAMTableDef,
LPISAMBOOKMARK lpISAMBookmark)
{
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
if (lpISAMTableDef->lpFile != NULL)
{
lpISAMBookmark->currentRecord = lpISAMTableDef->lpFile->currentRecord;
}
else
{
lpISAMBookmark->currentRecord = lpISAMTableDef->iRecord;
}
if (lpISAMTableDef->virtualInstances)
{
lpISAMBookmark->currentInstance = lpISAMTableDef->virtualInstances->currentInstance;
}
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMPosition(LPISAMTABLEDEF lpISAMTableDef,
LPISAMBOOKMARK ISAMBookmark)
{
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
if ( lpISAMTableDef->lpFile && lpISAMTableDef->lpFile->tempEnum->IsValid())
{
BOOL fStatus = lpISAMTableDef->lpFile->pAllRecords->Lookup
( (WORD)(ISAMBookmark->currentRecord - 1), (void* &)lpISAMTableDef->lpFile->record);
if (fStatus && lpISAMTableDef->lpFile->record)
{
//Update bookmark to next entry
lpISAMTableDef->lpFile->currentRecord = ISAMBookmark->currentRecord;// + 1;
}
else
{
lpISAMTableDef->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
}
else
{
lpISAMTableDef->iRecord = (SDWORD) ISAMBookmark->currentRecord;
}
if (lpISAMTableDef->virtualInstances)
{
lpISAMTableDef->virtualInstances->currentInstance = ISAMBookmark->currentInstance;
}
return NO_ISAM_ERR;
}
/***************************************************************************/
/* Closes a specific table and deallocates the table definition */
SWORD INTFUNC ISAMCloseTable(LPISAMTABLEDEF lpISAMTableDef)
{
//Check if lpISAMTableDef exists
if (! lpISAMTableDef)
return NO_ISAM_ERR;
/* Close the dBASE file */
lpISAMTableDef->lpISAM->errcode = NO_ISAM_ERR;
if (lpISAMTableDef->lpFile != NULL)
{
//Release interface pointers if applicable
//Empty out all instances
if (lpISAMTableDef->lpFile->pAllRecords)
{
for(POSITION pos = lpISAMTableDef->lpFile->pAllRecords->GetStartPosition(); pos != NULL; )
{
WORD key = 0;
IWbemClassObject* pa = NULL;
lpISAMTableDef->lpFile->pAllRecords->GetNextAssoc( pos, key, (void*&)pa );
if (pa)
{
pa->Release();
}
}
delete (lpISAMTableDef->lpFile->pAllRecords);
lpISAMTableDef->lpFile->pAllRecords = NULL;
}
if (lpISAMTableDef->lpFile->tempEnum)
{
delete (lpISAMTableDef->lpFile->tempEnum);
lpISAMTableDef->lpFile->tempEnum = NULL;
}
}
if (lpISAMTableDef->pBStrTableName)
{
delete (lpISAMTableDef->pBStrTableName);
lpISAMTableDef->pBStrTableName = NULL;
}
if (lpISAMTableDef->pSingleTable)
{
lpISAMTableDef->pSingleTable->Release();
lpISAMTableDef->pSingleTable = NULL;
}
TidyupPassthroughMap(lpISAMTableDef->passthroughMap);
lpISAMTableDef->passthroughMap = NULL;
if (lpISAMTableDef->pGateway2)
{
delete lpISAMTableDef->pGateway2;
lpISAMTableDef->pGateway2 = NULL;
}
if (lpISAMTableDef->pColumnInfo)
{
delete (lpISAMTableDef->pColumnInfo);
lpISAMTableDef->pColumnInfo = NULL;
}
if (lpISAMTableDef->pContext)
{
lpISAMTableDef->pContext->Release();
lpISAMTableDef->pContext = NULL;
}
if (lpISAMTableDef->lpFile)
{
GlobalUnlock(GlobalPtrHandle(lpISAMTableDef->lpFile));
GlobalFree(GlobalPtrHandle(lpISAMTableDef->lpFile));
lpISAMTableDef->lpFile = NULL;
}
delete lpISAMTableDef->virtualInstances;
lpISAMTableDef->virtualInstances = NULL;
GlobalUnlock(GlobalPtrHandle(lpISAMTableDef));
GlobalFree(GlobalPtrHandle(lpISAMTableDef));
lpISAMTableDef = NULL;
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMDeleteTable(LPISAM lpISAM, LPUSTR lpszTableName)
{
return ISAM_NOTSUPPORTED;
/*
UCHAR szFilename[MAX_DATABASE_NAME_LENGTH+MAX_TABLE_NAME_LENGTH+6];
// Create the filename
lpISAM->errcode = NO_ISAM_ERR;
lstrcpy((char*)szFilename, (char*)lpISAM->szDatabase);
lstrcat((char*)szFilename, "\\");
lstrcat((char*)szFilename, lpszTableName);
lstrcat((char*)szFilename, ".DBF");
// Delete the file
dBaseDestroy((char*)szFilename);
return NO_ISAM_ERR;
*/
}
/***************************************************************************/
// Checked for SetInterfaceSecurityEx on IWbemServices and IEnumWbemClassObject
SWORD INTFUNC ISAMPrepare(LPISAM lpISAM, UCHAR FAR *szSqlStr, SDWORD cbSqlStr,
LPISAMSTATEMENT FAR *lplpISAMStatement,
LPUSTR lpszTablename, UWORD FAR *lpParameterCount
#ifdef IMPLTMT_PASSTHROUGH
, LPSTMT lpstmt
#endif
)
{
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare\n"));
//For now disable Passthrough SQL
// lpISAM->errcode = ISAM_NOTSUPPORTED;
// return ISAM_NOTSUPPORTED;
/*
//Test
CBString s1;
CBString s2;
CBString s3;
CBString s4;
CBString s5;
s1.AddString("", FALSE);
s2.AddString(NULL, FALSE);
s3.AddString("\\\\.", FALSE);
s4.AddString("\\\\SaiWong4", FALSE);
s5.AddString("\\\\SaiWong2", FALSE);
CServerLocationCheck one(s1);
CServerLocationCheck two(s2);
CServerLocationCheck three(s3);
CServerLocationCheck four(s4);
CServerLocationCheck five(s5);
*/
HGLOBAL h;
LPISAMSTATEMENT lpISAMStatement;
lpISAM->errcode = NO_ISAM_ERR;
h = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof (ISAMSTATEMENT));
if (h == NULL || (lpISAMStatement = (LPISAMSTATEMENT) GlobalLock (h)) == NULL) {
if (h)
GlobalFree(h);
lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 1\n"));
//Initialize passthrough parameters
lpISAMStatement->pProv = NULL;
lpISAMStatement->currentRecord = 0;
lpISAMStatement->tempEnum = new CSafeIEnumWbemClassObject();
lpISAMStatement->firstPassthrInst = NULL;
lpISAMStatement->classDef = NULL;
lpISAMStatement->tempEnum2 = new CSafeIEnumWbemClassObject();
if ((cbSqlStr == 15) && (!_fmemicmp(szSqlStr, "MessageBox(?,?)", 15))) {
s_lstrcpy(lpszTablename, "");
*lpParameterCount = 2;
lpISAMStatement->lpISAM = lpISAM;
lpISAMStatement->resultSet = FALSE;
lpISAMStatement->lpszParam1 = NULL;
lpISAMStatement->cbParam1 = SQL_NULL_DATA;
lpISAMStatement->lpszParam2 = NULL;
lpISAMStatement->cbParam2 = SQL_NULL_DATA;
}
#ifdef IMPLTMT_PASSTHROUGH
else if (TRUE)
{
//Try passthrough
*lpParameterCount = 0;
lpISAMStatement->lpISAM = lpISAM;
lpISAMStatement->resultSet = TRUE;
lpISAMStatement->lpszParam1 = NULL;
lpISAMStatement->cbParam1 = SQL_NULL_DATA;
lpISAMStatement->lpszParam2 = NULL;
lpISAMStatement->cbParam2 = SQL_NULL_DATA;
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 2\n"));
/* No. Create a PASSTHROUGH parse tree */
SCODE sc = Parse(lpstmt, lpISAM, (LPUSTR) szSqlStr,
cbSqlStr, &(lpstmt->lpSqlStmt));
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 3\n"));
if (sc != SQL_SUCCESS) {
FreeTree(lpstmt->lpSqlStmt);
lpstmt->lpSqlStmt = NULL;
delete lpISAMStatement->tempEnum;
delete lpISAMStatement->tempEnum2;
GlobalUnlock(h);
GlobalFree(h);
lpISAM->errcode = ISAM_NOTSUPPORTED;
return ISAM_NOTSUPPORTED;
}
//Need to do a semantic check so that any
//Table.* will get expanded
sc = SemanticCheck(lpstmt, &(lpstmt->lpSqlStmt),
ROOT_SQLNODE, FALSE, ISAMCaseSensitive(lpstmt->lpdbc->lpISAM),
NO_SQLNODE, NO_SQLNODE);
if (sc != SQL_SUCCESS) {
FreeTree(lpstmt->lpSqlStmt);
lpstmt->lpSqlStmt = NULL;
delete lpISAMStatement->tempEnum;
delete lpISAMStatement->tempEnum2;
GlobalUnlock(h);
GlobalFree(h);
lpISAM->errcode = ISAM_NOTSUPPORTED;
return ISAM_NOTSUPPORTED;
}
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 3b\n"));
//Generate WQL statement using parse tree
LPSQLNODE lpRootNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
LPSQLNODE lpSqlNode2 = ToNode(lpstmt->lpSqlStmt, lpRootNode->node.root.sql);
char* fullWQL = NULL;
BOOL fHasAggregateFunctions = FALSE;
TableColumnInfo selectInfo (&lpRootNode, &lpSqlNode2, WQL_MULTI_TABLE);
CMapWordToPtr* passthroughMap;
selectInfo.BuildFullWQL(&fullWQL, &passthroughMap);
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 3c\n"));
//Extra check for aggregate functions what WQL does not support
//so we must fail SQL passthrough
if ( selectInfo.HasAggregateFunctions() )
{
fHasAggregateFunctions = TRUE;
}
//At this point we can check for 'SELECT * FROM .....'
//If this is so we need to work out the full column list
//and re-parse and try again (only for single tables)
if ( selectInfo.IsSelectStar() && selectInfo.IsZeroOrOneList() )
{
//get new query string
char* lpWQLStr = NULL;
char* lpWQLSelectStarList = NULL;
BOOL fIsThisDistinct = selectInfo.IsDistinct();
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 4\n"));
ISAMGetSelectStarList(&lpWQLSelectStarList, &selectInfo, lpISAM);
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 5\n"));
//clean up parse tree
FreeTree(lpstmt->lpSqlStmt);
lpstmt->lpSqlStmt = NULL;
//clean up passthrough map
TidyupPassthroughMap(passthroughMap);
passthroughMap = NULL;
ISAMStringConcat(&lpWQLStr, "SELECT ");
//Add tail end of previous string
char* oldString = fullWQL;
oldString += 7; //skip over SELECT
if ( fIsThisDistinct )
{
ISAMStringConcat(&lpWQLStr, "distinct ");
oldString += 9; //skip over DISTINCT
}
if (lpWQLSelectStarList)
{
ISAMStringConcat(&lpWQLStr, lpWQLSelectStarList);
}
ISAMStringConcat(&lpWQLStr, oldString);
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 6\n"));
CString sMessage;
sMessage.Format("\nWBEM ODBC Driver : detected select * : reparsing query :\n%s\n", lpWQLStr);
ODBCTRACE(sMessage);
// No. Create a PASSTHROUGH parse tree
sc = Parse(lpstmt, lpISAM, (LPUSTR) lpWQLStr,
lstrlen(lpWQLStr), &(lpstmt->lpSqlStmt));
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 7\n"));
if (lpWQLStr)
delete lpWQLStr;
if (sc != SQL_SUCCESS) {
FreeTree(lpstmt->lpSqlStmt);
lpstmt->lpSqlStmt = NULL;
delete lpISAMStatement->tempEnum;
delete lpISAMStatement->tempEnum2;
GlobalUnlock(h);
GlobalFree(h);
lpISAM->errcode = ISAM_NOTSUPPORTED;
return ISAM_NOTSUPPORTED;
}
//Generate WQL statement using parse tree
lpRootNode = ToNode(lpstmt->lpSqlStmt, ROOT_SQLNODE);
lpSqlNode2 = ToNode(lpstmt->lpSqlStmt, lpRootNode->node.root.sql);
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 8\n"));
delete fullWQL;
fullWQL = NULL;
TableColumnInfo selectInfo2 (&lpRootNode, &lpSqlNode2, WQL_MULTI_TABLE);
selectInfo2.BuildFullWQL(&fullWQL, &passthroughMap);
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 9\n"));
//Extra check for aggregate functions what WQL does not support
//so we must fail SQL passthrough
if ( selectInfo2.HasAggregateFunctions() )
{
fHasAggregateFunctions = TRUE;
}
}
_bstr_t sqltextBSTR = fullWQL;
delete fullWQL;
CString wqlTextDebug(_T("\nWBEM ODBC Driver : WQL query : "));
wqlTextDebug += (LPCTSTR)sqltextBSTR;
wqlTextDebug += _T("\n");
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 7b\n"));
//Get instances by executing query
sc = WBEM_E_FAILED;
char* lpTblQualifier = NULL;
// if (idxQual != NO_STRING)
// {
// lpTblQualifier = (LPSTR) ToString(lpRootNode, idxQual);
// }
// else
{
lpTblQualifier = lpstmt->lpdbc->lpISAM->szDatabase;
}
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 7c\n"));
lpISAMStatement->pProv = new CSafeWbemServices();
lpISAMStatement->pProv->SetInterfacePtr(lpstmt->lpdbc->lpISAM, (LPUSTR) lpTblQualifier, (SWORD) lstrlen(lpTblQualifier));
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 7d\n"));
lpISAMStatement->passthroughMap = passthroughMap;
//Get prototype 'class' definition
if (lpISAMStatement->pProv->IsValid())
{
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 10\n"));
sc = lpISAMStatement->tempEnum2->SetInterfacePtr(lpstmt->lpdbc->lpISAM, WMI_PROTOTYPE, sqltextBSTR, lpISAMStatement->pProv);
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 11\n"));
//Extra check for aggregate functions what WQL does not support
//so we must fail SQL passthrough
if ( fHasAggregateFunctions )
{
sc = WBEM_E_NOT_SUPPORTED;
}
}
else
{
sc = WBEM_E_NOT_SUPPORTED;
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 7e\n"));
}
if ( (sc == WBEM_E_NOT_SUPPORTED) || (sc == WBEM_E_FAILED) || (sc == WBEM_E_INVALID_QUERY) || (sc == WBEM_E_NOT_FOUND) || (sc == WBEM_E_ACCESS_DENIED) )
{
if ( fHasAggregateFunctions )
{
ODBCTRACE(_T("\nWBEM ODBC Driver : Failing SQL passthrough as original SQL query has aggregate functions which WQL does not support\n"));
}
else
{
ODBCTRACE(_T("\nWBEM ODBC Driver : Getting prototype failed\n"));
}
//ExecQuery failed
delete lpISAMStatement->pProv;
lpISAMStatement->pProv = NULL;
TidyupPassthroughMap(lpISAMStatement->passthroughMap);
lpISAMStatement->passthroughMap = NULL;
FreeTree(lpstmt->lpSqlStmt);
lpstmt->lpSqlStmt = NULL;
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 12\n"));
delete lpISAMStatement->tempEnum;
delete lpISAMStatement->tempEnum2;
GlobalUnlock(h);
GlobalFree(h);
lpISAM->errcode = ISAM_NOTSUPPORTED;
return ISAM_NOTSUPPORTED;
}
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 12\n"));
IWbemServicesPtr myServicesPtr = NULL;
ISAMGetIWbemServices(lpISAM, *(lpISAMStatement->pProv), myServicesPtr);
IEnumWbemClassObjectPtr myIEnumWbemClassObject = NULL;
lpISAMStatement->tempEnum2->GetInterfacePtr(myIEnumWbemClassObject);
// CBString myServerStr;
// myServerStr.AddString( (LPSTR)lpISAM->szServer, FALSE );
// CServerLocationCheck myCheck (myServerStr);
BOOL fIsLocalConnection = lpISAM->fIsLocalConnection;//myCheck.IsLocal();
ISAMSetCloaking2(myIEnumWbemClassObject,
fIsLocalConnection,
lpISAM->fW2KOrMore,
lpISAM->dwAuthLevel,
lpISAM->dwImpLevel,
lpISAM->gpAuthIdentity);
/*
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(myIEnumWbemClassObject, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
}
else
{
SetInterfaceSecurityEx(myIEnumWbemClassObject,
lpISAM->gpAuthIdentity,
gpPrincipal,
lpISAM->dwAuthLevel,
lpISAM->dwImpLevel);
}
*/
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 13\n"));
//There should be only 1 instance which is the class definition
ULONG puReturned = 0;
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 14\n"));
myIEnumWbemClassObject->Reset();
if (myIEnumWbemClassObject->Next(-1, 1, &(lpISAMStatement->classDef), &puReturned) != S_OK)
{
ODBCTRACE(_T("\nWBEM ODBC Driver : Getting Prototype instance failed\n"));
delete lpISAMStatement->pProv;
lpISAMStatement->pProv = NULL;
TidyupPassthroughMap(lpISAMStatement->passthroughMap);
lpISAMStatement->passthroughMap = NULL;
FreeTree(lpstmt->lpSqlStmt);
lpstmt->lpSqlStmt = NULL;
delete lpISAMStatement->tempEnum;
delete lpISAMStatement->tempEnum2;
GlobalUnlock(h);
GlobalFree(h);
lpISAM->errcode = ISAM_NOTSUPPORTED;
return ISAM_NOTSUPPORTED;
}
//Now execute the real query
if (lpISAMStatement->pProv->IsValid())
{
sc = lpISAMStatement->tempEnum->SetInterfacePtr(lpISAM, WMI_EXEC_FWD_ONLY, sqltextBSTR, lpISAMStatement->pProv);
ODBCTRACE(_T("\nWBEM ODBC Driver :ISAMPrepare : Pos 15\n"));
//As semi-synchronous does not indicate if any error occurs
//we need to get the first record back now
if ( SUCCEEDED(sc) )
{
IEnumWbemClassObjectPtr myIEnumWbemClassObj1 = NULL;
lpISAMStatement->tempEnum->GetInterfacePtr(myIEnumWbemClassObj1);
ISAMSetCloaking2(myIEnumWbemClassObj1,
fIsLocalConnection,
lpISAM->fW2KOrMore,
lpISAM->dwAuthLevel,
lpISAM->dwImpLevel,
lpISAM->gpAuthIdentity);
/*
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(myIEnumWbemClassObj1, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
}
else
{
SetInterfaceSecurityEx(myIEnumWbemClassObj1,
lpISAM->gpAuthIdentity,
gpPrincipal,
lpISAM->dwAuthLevel,
lpISAM->dwImpLevel);
}
*/
ULONG numReturned = 0;
sc = myIEnumWbemClassObj1->Next(-1, 1, &(lpISAMStatement->firstPassthrInst), &numReturned);
}
}
else
{
sc = WBEM_E_NOT_SUPPORTED;
}
CString sSCODE;
sSCODE.Format("\nMAGIC NUMBER = 0x%X\n", sc);
ODBCTRACE(sSCODE);
if ( sc != WBEM_S_NO_ERROR )
{
ODBCTRACE(_T("\nWBEM ODBC Driver : Passthrough SQL Failed or Not Supported\n"));
//ExecQuery failed
lpISAM->errcode = ERR_PASSTGHONLY_NOTSUPP;
//default error string
((char*)lpstmt->szISAMError)[0] = 0;
CString sDefaultError;
sDefaultError.LoadString(STR_EXECQUERY);
sprintf((char*)lpstmt->szError, "%s 0x%X", sDefaultError, sc);
lpISAM->errcode = ERR_WBEM_SPECIFIC;
//Test here
//need to get the WBEM specific error
IErrorInfo* pEI = NULL;
IWbemClassObject *pErrorObject = NULL;
if(GetErrorInfo(0, &pEI) == S_OK)
{
pEI->QueryInterface(IID_IWbemClassObject, (void**)&pErrorObject);
pEI->Release();
}
if (pErrorObject)
{
VARIANT varString;
if (pErrorObject->InheritsFrom(L"__NotifyStatus") != WBEM_NO_ERROR)
{
// fprintf(stdout, "Unrecognized Error Object type\n");
}
else if (pErrorObject->InheritsFrom(L"__ExtendedStatus") == WBEM_NO_ERROR)
{
sc = pErrorObject->Get(L"Description", 0L, &varString, NULL, NULL);
if ( (sc == S_OK) && (varString.vt == VT_BSTR) )
{
lstrcpy((char*)lpstmt->szISAMError, "");
wcstombs((char*)lpstmt->szError,varString.bstrVal ? varString.bstrVal : L" ", MAX_ERROR_LENGTH);
lpISAM->errcode = ERR_WBEM_SPECIFIC;
VariantClear(&varString);
}
}
pErrorObject->Release();
}
delete lpISAMStatement->pProv;
lpISAMStatement->pProv = NULL;
lpISAMStatement->classDef->Release();
TidyupPassthroughMap(lpISAMStatement->passthroughMap);
lpISAMStatement->passthroughMap = NULL;
SWORD savedErrorCode = lpISAM->errcode;
FreeTree(lpstmt->lpSqlStmt);
lpstmt->lpSqlStmt = NULL;
delete lpISAMStatement->tempEnum;
delete lpISAMStatement->tempEnum2;
GlobalUnlock(h);
GlobalFree(h);
lpISAM->errcode = savedErrorCode;
return ISAM_NOTSUPPORTED;
}
//ExecQuery succeeded
myServicesPtr = NULL;
ISAMGetIWbemServices(lpISAM, *(lpISAMStatement->pProv), myServicesPtr);
//free up enumeration before resetting to NULL
IEnumWbemClassObject* tempEnum = myIEnumWbemClassObject.Detach();
if (tempEnum)
tempEnum->Release();
myIEnumWbemClassObject = NULL;
lpISAMStatement->tempEnum->GetInterfacePtr(myIEnumWbemClassObject);
ISAMSetCloaking2(myIEnumWbemClassObject,
fIsLocalConnection,
lpISAM->fW2KOrMore,
lpISAM->dwAuthLevel,
lpISAM->dwImpLevel,
lpISAM->gpAuthIdentity);
/*
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(myIEnumWbemClassObject, lpISAM->dwAuthLevel, lpISAM->dwImpLevel);
}
else
{
SetInterfaceSecurityEx(myIEnumWbemClassObject,
lpISAM->gpAuthIdentity,
gpPrincipal,
lpISAM->dwAuthLevel,
lpISAM->dwImpLevel);
}
*/
ODBCTRACE(_T("\nWBEM ODBC Driver : Passthrough SQL succeeded, getting instances\n"));
//Copy table name
lpszTablename[0] = 0;
wchar_t* virTbl = WBEMDR32_VIRTUAL_TABLE;
wcstombs((char*)lpszTablename, virTbl, MAX_TABLE_NAME_LENGTH);
lpszTablename[MAX_TABLE_NAME_LENGTH] = 0;
//Free the Parse tree.
//A new Parse tree will be created for
//SELECT * FROM WBEMDR32VirtualTable
FreeTree(lpstmt->lpSqlStmt);
lpstmt->lpSqlStmt = NULL;
}
#else
else if ((cbSqlStr == 3) && (!_fmemicmp(szSqlStr, "SQL", 3))) {
s_lstrcpy(lpszTablename, "SQL");
*lpParameterCount = 0;
lpISAMStatement->lpISAM = lpISAM;
lpISAMStatement->resultSet = TRUE;
lpISAMStatement->lpszParam1 = NULL;
lpISAMStatement->cbParam1 = SQL_NULL_DATA;
lpISAMStatement->lpszParam2 = NULL;
lpISAMStatement->cbParam2 = SQL_NULL_DATA;
}
else {
test if we reach here
delete lpISAMStatement->tempEnum;
delete lpISAMStatement->tempEnum2;
GlobalUnlock(h);
GlobalFree(h);
lpISAM->errcode = ISAM_NOTSUPPORTED;
return ISAM_NOTSUPPORTED;
}
#endif
*lplpISAMStatement = lpISAMStatement;
return NO_ISAM_ERR;
}
// Checked for SetInterfaceSecurityEx on IWbemServices
void INTFUNC ISAMGetSelectStarList(char** lpWQLSelectStarList, TableColumnInfo* pSelectInfo, LPISAM lpISAM)
{
//First check you have one table in the select list
char* mytable = NULL;
BOOL fDummyValue = FALSE;
pSelectInfo->BuildTableList(&mytable, fDummyValue);
if ( mytable && lstrlen (mytable) )
{
//got the table, now fetch the column names
CBString pBStrTableName;
pBStrTableName.AddString((LPSTR)mytable, FALSE);
IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAM->m_Locale);
//Get class object based on table name
IWbemClassObjectPtr pSingleTable = NULL;
IWbemServicesPtr pGateway = NULL;
ISAMGetGatewayServer(pGateway, lpISAM, (LPUSTR)lpISAM->szDatabase, (SWORD) lstrlen(lpISAM->szDatabase));
if ( FAILED(pGateway->GetObject(pBStrTableName.GetString(), 0, pContext, &pSingleTable, NULL)))
{
if (pContext)
pContext->Release();
if (mytable)
delete mytable;
return;
}
if (pContext)
pContext->Release();
//Get the names of all the properties/columns
SAFEARRAY FAR* rgSafeArray = NULL;
SCODE scT = pSingleTable->GetNames ( NULL, 0, NULL, &rgSafeArray );
//Work out number of properties/columns
LONG iLBound = 0;
LONG iUBound = 0;
SafeArrayGetLBound(rgSafeArray, 1, &iLBound );
SafeArrayGetUBound(rgSafeArray, 1, &iUBound );
//Loop through column names
char pColumnName [MAX_COLUMN_NAME_LENGTH+1];
BOOL fFirstTime = TRUE;
for (LONG loop = iLBound; loop <= iUBound; loop++)
{
BSTR lpbString;
if ( FAILED(SafeArrayGetElement(rgSafeArray, &loop, &lpbString)) )
{
if (mytable)
delete mytable;
SafeArrayUnlock(rgSafeArray); //SAI ADDED
SafeArrayDestroy(rgSafeArray);//SAI ADDED
//(11) Should we also release pSingleTable
return;
}
//copy column name
pColumnName[0] = 0;
wcstombs(pColumnName, lpbString, MAX_COLUMN_NAME_LENGTH);
pColumnName[MAX_COLUMN_NAME_LENGTH] = 0;
//filters - check for system properties
BOOL fAddToList = TRUE;
if (! lpISAM->fSysProps && !_strnicmp("__", pColumnName, 2))
{
fAddToList = FALSE;
}
//filters - check for lazy properties
if (fAddToList)
{
BOOL fIsLazyProperty = FALSE;
//Now get the qualifiers (if available)
IWbemQualifierSet* pQualifierSet = NULL;
if ( S_OK == (pSingleTable->GetPropertyQualifierSet
(lpbString, &pQualifierSet)) )
{
//Get the lazy qualifer (if applicable)
VARIANT pValLazy;
BSTR lazyStr = SysAllocString(WBEMDR32_L_LAZY);
if ( S_OK == (pQualifierSet->Get(lazyStr, 0, &pValLazy, NULL)) )
{
fAddToList = FALSE;
VariantClear(&pValLazy);
}
SysFreeString(lazyStr);
//Tidy up
if (pQualifierSet)
pQualifierSet->Release();
}
}
//add to select list
if (fAddToList)
{
if (!fFirstTime)
{
ISAMStringConcat(lpWQLSelectStarList, ", ");
}
ISAMStringConcat(lpWQLSelectStarList, pColumnName);
fFirstTime = FALSE;
}
SysFreeString(lpbString);
}
}
}
/***************************************************************************/
SWORD INTFUNC ISAMParameter(LPISAMSTATEMENT lpISAMStatement, UWORD ipar,
SWORD fCType, PTR rgbValue, SDWORD cbValue)
{
lpISAMStatement->lpISAM->errcode = NO_ISAM_ERR;
if (fCType != SQL_C_CHAR) {
lpISAMStatement->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
if (cbValue > MAX_CHAR_LITERAL_LENGTH) {
lpISAMStatement->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
if (cbValue == SQL_NULL_DATA)
cbValue = 0;
if (ipar == 1) {
lpISAMStatement->lpszParam1 = (LPSTR)rgbValue;
lpISAMStatement->cbParam1 = cbValue;
}
else if (ipar == 2) {
lpISAMStatement->lpszParam2 = (LPSTR)rgbValue;
lpISAMStatement->cbParam2 = cbValue;
}
else {
lpISAMStatement->lpISAM->errcode = ISAM_ERROR;
return ISAM_ERROR;
}
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMExecute(LPISAMSTATEMENT lpISAMStatement,
SDWORD FAR *lpcRowCount)
{
lpISAMStatement->lpISAM->errcode = NO_ISAM_ERR;
if (lpISAMStatement->resultSet)
{
// *lpcRowCount = 2;
//Return number of READ instances
//we never know the total number of instances returned
//via passthrough SQL (we get them in batches of 10)
//*lpcRowCount = lpISAMStatement->pAllRecords->GetCount();
*lpcRowCount = 0;
}
else
{
MessageBox(NULL, lpISAMStatement->lpszParam1,
lpISAMStatement->lpszParam2, 0);
*lpcRowCount = 0;
}
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMFreeStatement(LPISAMSTATEMENT lpISAMStatement)
{
lpISAMStatement->lpISAM->errcode = NO_ISAM_ERR;
//Free 1st SQL passthrough instance (if not already freed)
if (lpISAMStatement->firstPassthrInst)
{
lpISAMStatement->firstPassthrInst->Release();
lpISAMStatement->firstPassthrInst = NULL;
}
//Free Enumeration of Class definitions
if (lpISAMStatement->tempEnum)
{
delete lpISAMStatement->tempEnum;
lpISAMStatement->tempEnum = NULL;
}
if (lpISAMStatement->tempEnum2)
{
delete lpISAMStatement->tempEnum2;
lpISAMStatement->tempEnum2 = NULL;
}
if (lpISAMStatement->pProv)
{
delete lpISAMStatement->pProv;
lpISAMStatement->pProv = NULL;
}
if (lpISAMStatement->passthroughMap)
{
TidyupPassthroughMap(lpISAMStatement->passthroughMap);
lpISAMStatement->passthroughMap = NULL;
}
GlobalUnlock(GlobalPtrHandle(lpISAMStatement));
GlobalFree(GlobalPtrHandle(lpISAMStatement));
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMSetTxnIsolation(LPISAM lpISAM, UDWORD fTxnIsolationLevel)
{
/* Select one of the isolation modes from TxnIsolationOption */
if (!(fTxnIsolationLevel & lpISAM->fTxnIsolationOption)) {
lpISAM->errcode = ISAM_NOTSUPPORTED;
return ISAM_NOTSUPPORTED;
}
lpISAM->errcode = NO_ISAM_ERR;
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMCommitTxn(LPISAM lpISAM)
{
lpISAM->errcode = NO_ISAM_ERR;
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMRollbackTxn(LPISAM lpISAM)
{
lpISAM->errcode = NO_ISAM_ERR;
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMClose(LPISAM lpISAM)
{
lpISAM->errcode = NO_ISAM_ERR;
if (lpISAM->pNamespaceMap)
{
if (lpISAM->pNamespaceMap->GetCount ())
{
CString key;
CNamespace *pNamespace;
for (POSITION pos = lpISAM->pNamespaceMap->GetStartPosition (); pos != NULL; )
{
if (pos)
{
lpISAM->pNamespaceMap->GetNextAssoc (pos, key, (CObject*&)pNamespace);
delete pNamespace;
}
}
}
delete lpISAM->pNamespaceMap;
}
if (lpISAM->m_Locale)
{
delete (lpISAM->m_Locale);
lpISAM->m_Locale = NULL;
}
if (lpISAM->m_Authority)
{
delete (lpISAM->m_Authority);
lpISAM->m_Authority = NULL;
}
if (lpISAM->gpAuthIdentity)
{
WbemFreeAuthIdentity( lpISAM->gpAuthIdentity );
lpISAM->gpAuthIdentity = NULL;
}
if (lpISAM->Impersonate)
{
delete (lpISAM->Impersonate);
lpISAM->Impersonate = NULL;
}
if (lpISAM->hKernelApi)
{
BOOL status = FreeLibrary(lpISAM->hKernelApi);
lpISAM->hKernelApi = NULL;
if (! status)
{
DWORD err = GetLastError();
CString message ("\n\n***** FreeLibrary(2) KERNEL32 failed : %ld*****\n\n", err);
ODBCTRACE(message);
}
}
GlobalUnlock(GlobalPtrHandle(lpISAM));
GlobalFree(GlobalPtrHandle(lpISAM));
return NO_ISAM_ERR;
}
/***************************************************************************/
void INTFUNC ISAMGetErrorMessage(LPISAM lpISAM, LPUSTR lpszErrorMessage)
{
LoadString(s_hModule, lpISAM->errcode, (LPSTR)lpszErrorMessage,
MAX_ERROR_LENGTH+1);
}
/***************************************************************************/
LPSQLTYPE INTFUNC ISAMGetColumnType(
LPISAMTABLEDEF lpISAMTableDef,
UWORD icol)
{
/* There may be more than one entry in SQLTypes[] for any given SQL_x type, */
/* therefore we need to compare on the type name string */
ClassColumnInfoBase* cInfoBase = lpISAMTableDef->pColumnInfo;
if ( !cInfoBase->IsValid() )
{
return NULL;
}
UWORD cNumberOfCols = cInfoBase->GetNumberOfColumns();
if (icol >= cNumberOfCols)
return NULL;
UCHAR* puTypeName = NULL;
if ( !cInfoBase->GetTypeName(icol, puTypeName) )
{
return NULL;
}
UCHAR szTypeName[MAX_COLUMN_NAME_LENGTH+1];
LONG cLength = strlen ((char*)puTypeName);
memcpy(szTypeName, (char*)puTypeName, cLength);
szTypeName[cLength] = 0;
return GetType2(szTypeName);
}
/***************************************************************************/
BOOL INTFUNC ISAMCaseSensitive(LPISAM lpISAM)
{
return FALSE;
}
/***************************************************************************/
LPUSTR INTFUNC ISAMName(LPISAM lpISAM)
{
char* pName = new char [3 + 1];
pName[0] = 0;
sprintf (pName, "%s", "WMI");
return (LPUSTR)pName;
/*
char* lpRootDb = (char*)lpISAM->szRootDb;
IWbemServices* pProv = ISAMGetGatewayServer(lpISAM, (LPUSTR)lpRootDb, lstrlen(lpRootDb));
if (!pProv)
{
return NULL;
}
IWbemClassObject * pClassObj = NULL;
char* pName = NULL;
BSTR hmomIdBSTR = SysAllocString(WBEMDR32_L_CIMOMIDENTIFICATION);
IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAM->m_Locale);
SCODE sc = pProv->GetObject(hmomIdBSTR, 0, pContext, &pClassObj, NULL);
if (pContext)
pContext->Release();
SysFreeString(hmomIdBSTR);
if (sc == S_OK)
{
VARIANTARG var;
VariantInit(&var);
BSTR serverBSTR = SysAllocString(WBEMDR32_L_SERVER);
pClassObj->Get(serverBSTR,0,&var, NULL, NULL);
SysFreeString(serverBSTR);
LONG lLength = wcslen(var.bstrVal);
char* pTemp = new char [lLength + 1];
pTemp[0] = 0;
wcstombs(pTemp, var.bstrVal, lLength);
pTemp[lLength] = 0;
pName = new char [lLength + 10];
pName[0] = 0;
lstrcpy(pName, "MOServer@");
lstrcat(pName, pTemp);
delete pTemp;
VariantClear(&var);
pClassObj->Release();
}
if (pProv)
pProv->Release();
return (LPUSTR)pName;
*/
}
/***************************************************************************/
// Checked for SetInterfaceSecurityEx on IWbemServices
LPUSTR INTFUNC ISAMServer(LPISAM lpISAM)
{
ODBCTRACE("\nWBEM ODBC Driver : ISAMServer\n");
char* lpRootDb = (char*)lpISAM->szRootDb;
IWbemServicesPtr pProv = NULL;
ISAMGetGatewayServer(pProv, lpISAM, (LPUSTR)lpRootDb, (SWORD) lstrlen(lpRootDb));
if (pProv == NULL)
{
return NULL;
}
IWbemClassObject * pClassObj = NULL;
char* pName = NULL;
BSTR hmomIdBSTR = SysAllocString(WBEMDR32_L_CIMOMIDENTIFICATION);
IWbemContext* pContext = ISAMCreateLocaleIDContextObject(lpISAM->m_Locale);
SCODE sc = pProv->GetObject(hmomIdBSTR, 0, pContext, &pClassObj, NULL);
if (pContext)
pContext->Release();
SysFreeString(hmomIdBSTR);
if (sc == S_OK)
{
VARIANTARG var;
BSTR serverBSTR = SysAllocString(WBEMDR32_L_SERVER);
pClassObj->Get(serverBSTR,0,&var, NULL, NULL);
SysFreeString(serverBSTR);
LONG lLength = wcslen(var.bstrVal);
pName = new char [lLength + 1];
pName[0] = 0;
wcstombs(pName, var.bstrVal, lLength);
pName[lLength] = 0;
VariantClear(&var);
long rc = pClassObj->Release();
}
return (LPUSTR)pName;
}
/***************************************************************************/
LPUSTR INTFUNC ISAMVersion(LPISAM lpISAM)
{
char* pVersion = new char [10 + 1];
pVersion[0] = 0;
sprintf (pVersion, "%s", "01.00.0000");
return (LPUSTR)pVersion;
}
/***************************************************************************/
LPCUSTR INTFUNC ISAMDriver(LPISAM lpISAM)
{
return (LPCUSTR) "WBEMDR32.DLL";
}
/***************************************************************************/
SWORD INTFUNC ISAMMaxTableNameLength(LPISAM lpISAM)
{
return MAX_TABLE_NAME_LENGTH;//i.e.128
}
/***************************************************************************/
SWORD INTFUNC ISAMMaxColumnNameLength(LPISAM lpISAM)
{
return MAX_COLUMN_NAME_LENGTH;//i.e.128
}
/***************************************************************************/
LPUSTR INTFUNC ISAMUser(LPISAM lpISAM)
{
return (LPUSTR) lpISAM->szUser;
}
/***************************************************************************/
LPUSTR INTFUNC ISAMDatabase(LPISAM lpISAM)
{
return (LPUSTR) lpISAM->szDatabase;
}
/***************************************************************************/
int INTFUNC ISAMSetDatabase (LPISAM lpISAM, LPUSTR database)
{
if (database && s_lstrlen(database) < MAX_DATABASE_NAME_LENGTH)
{
s_lstrcpy (lpISAM->szDatabase, database);
return TRUE;
}
else
return FALSE;
}
/***************************************************************************/
LPUSTR INTFUNC ISAMRoot (LPISAM lpISAM)
{
return (LPUSTR) lpISAM->szRootDb;
}
/***************************************************************************/
/* This code was copied from the original Dr DeeBee code and moved to */
/* this separate function for our uses */
static SWORD ISAMGetDoubleFromString(BSTR &pString, SDWORD cbValueMax, double &d, BOOL & isNull, BOOL &foundDecimalPoint)
{
isNull = TRUE;
BOOL neg = TRUE;
char* pTemp = new char [cbValueMax + 1];
pTemp[0] = 0;
SDWORD cbLen = wcstombs( pTemp, pString, cbValueMax);
pTemp[cbValueMax] = 0;
for (SDWORD i=0; i < cbLen; i++)
{
if (*pTemp != ' ')
break;
pTemp++;
}
neg = FALSE;
if (i < cbLen)
{
if (*pTemp == '-')
{
neg = TRUE;
pTemp++;
i++;
}
}
d = 0.0;
short scale = 0;
BOOL negexp = FALSE;
foundDecimalPoint = FALSE;
for (;i < cbLen; i++)
{
if (!foundDecimalPoint && (*pTemp == '.'))
foundDecimalPoint = TRUE;
else
{
if ((*pTemp == 'E') || (*pTemp == 'e'))
{
pTemp++;
i++;
if (i < cbLen)
{
if (*pTemp == '-')
{
negexp = TRUE;
pTemp++;
i++;
}
else if (*pTemp == '+')
{
negexp = FALSE;
pTemp++;
i++;
}
else
negexp = FALSE;
}
else
negexp = FALSE;
short exp = 0;
for (;i < cbLen; i++)
{
if ((*pTemp < '0') || (*pTemp > '9'))
{
delete pTemp;
return DBASE_ERR_CONVERSIONERROR;
}
exp = (exp * 10) + (*pTemp - '0');
pTemp++;
}
if (negexp)
scale = scale + exp;
else
scale = scale - exp;
break;
}
if ((*pTemp < '0') || (*pTemp > '9'))
{
delete pTemp;
return DBASE_ERR_CONVERSIONERROR;
}
d = (d * 10) + (*pTemp - '0');
isNull = FALSE;
if (foundDecimalPoint)
scale++;
}
pTemp++;
}
for (; (0 < scale); scale--)
d /= 10;
for (; (0 > scale); scale++)
d *= 10;
if (neg)
d = -d;
delete pTemp;
return DBASE_ERR_SUCCESS;
}
/***************************************************************************/
/* Template class to decode array variant value */
/* */
/* The fIsBinaryOutput parameter indicates if you */
/* want the output value a binary data or a string */
template <class T> SWORD ISAMGetArrayInfo (VARIANT &vVariantVal, T theValue,
PTR rgbValue, SDWORD cbValueMax, SDWORD FAR* pcbValue,
BOOL fIsBinaryOutput, SWORD wDSDT, UDWORD cbPrecision, long myVirIndex = -1)
{
//Check if we want all elements of the array or just one element
BOOL fAllElements = TRUE;
if (myVirIndex != -1)
{
fAllElements = FALSE;
}
//Get the value
SAFEARRAY FAR* pArray = vVariantVal.parray;
SafeArrayLock(pArray);
//Find out the bounds of the array
//Get the upper and lower bounds
long lLowerBound;
SafeArrayGetLBound(pArray, 1, &lLowerBound);
long lUpperBound;
SafeArrayGetUBound(pArray, 1, &lUpperBound);
*pcbValue = 0;
if (cbValueMax)
((char*)rgbValue)[0] = 0;
//Initialize
long cCount = 0;
SWORD wElemSize = sizeof (T);
//Setup the filter for the data
char filter [20];
filter[0] = 0;
//Character string length use to represent each element of array
SWORD wFullCharSize = 0;
if (!fIsBinaryOutput)
{
//Also setup the filter for the data
filter[0] = 0;
if ( wDSDT == WBEM_DSDT_REAL_ARRAY )
{
if (fAllElements)
{
//For character string output the format will be [precision.6f]
//Thus, we need room for the [ ] and the 'precision.6'
wFullCharSize = 9 + REAL_PRECISION;
sprintf (filter, "%s%d%s", "[%", REAL_PRECISION, ".6g]");
}
else
{
//For character string output the format will be precision.6f
//Thus, we need room for the 'precision.6'
wFullCharSize = 7 + REAL_PRECISION;
sprintf (filter, "%s%d%s", "%", REAL_PRECISION, ".6g");
}
}
else if ( wDSDT == WBEM_DSDT_DOUBLE_ARRAY )
{
if (fAllElements)
{
//For character string output the format will be [precision.6f]
//Thus, we need room for the [ ] and the 'precision.6'
wFullCharSize = 9 + DOUBLE_PRECISION;
sprintf (filter, "%s%d%s", "[%", DOUBLE_PRECISION, ".6g]");
}
else
{
//For character string output the format will be precision.6f
//Thus, we need room for the 'precision.6'
wFullCharSize = 7 + DOUBLE_PRECISION;
sprintf (filter, "%s%d%s", "%", DOUBLE_PRECISION, ".6g");
}
}
else
{
//For character string output the format will be [precision]
//We add 1 to the precision if the type is signed
//Thus, we need room for the [ ] and the
//ie 2 extra characters for unsigned and 3 for signed
//Integer type
//Check if signed
switch (wDSDT)
{
case WBEM_DSDT_SINT8_ARRAY:
case WBEM_DSDT_SINT16_ARRAY:
case WBEM_DSDT_SINT32_ARRAY:
{
//Signed
++cbPrecision;
if (fAllElements)
{
wFullCharSize = (SWORD) (cbPrecision + 2);
strcpy (filter, "[%ld]");
}
else
{
wFullCharSize = (SWORD) cbPrecision;
strcpy (filter, "%ld");
}
}
break;
case WBEM_DSDT_BOOL_ARRAY:
{
if (fAllElements)
{
wFullCharSize = (SWORD) (cbPrecision + 2);
strcpy (filter, "[%s]");
}
else
{
wFullCharSize = (SWORD) cbPrecision;
strcpy (filter, "%s");
}
}
break;
default:
{
if (fAllElements)
{
//Unsigned
wFullCharSize = (SWORD) (cbPrecision + 2);
strcpy (filter, "[%lu]");
}
else
{
//Unsigned
wFullCharSize = (SWORD) (cbPrecision);
strcpy (filter, "%lu");
}
}
break;
}
}
}
char* tempBuff = new char [wFullCharSize + 1];
//Loop through each entry to fetch the array data
BOOL fDoweHaveEnoughBufferSpace = FALSE;
long loop = 0;
for (long cIndex = lLowerBound; cIndex <= lUpperBound; cIndex++)
{
//Check we have enough buffer space
if (fIsBinaryOutput)
{
fDoweHaveEnoughBufferSpace = ((wElemSize + (*pcbValue)) <= cbValueMax) ? TRUE : FALSE;
}
else
{
fDoweHaveEnoughBufferSpace = ((wFullCharSize + (*pcbValue)) <= cbValueMax) ? TRUE : FALSE;
}
if ( fDoweHaveEnoughBufferSpace)
{
if ( SUCCEEDED(SafeArrayGetElement(pArray, &cIndex, &theValue)) )
{
//Check if we want to use this value
BOOL fUseThisValue = FALSE;
if (fAllElements)
{
fUseThisValue = TRUE;
}
else
{
if (loop == myVirIndex)
fUseThisValue = TRUE;
}
if (fUseThisValue)
{
if (fIsBinaryOutput)
{
//Copy
T* pTemp = (T*)rgbValue;
pTemp[cCount++] = theValue;
//Increment counter of number of bytes copied
(*pcbValue) += wElemSize;
}
else
{
tempBuff[0] = 0;
if (wDSDT == WBEM_DSDT_BOOL_ARRAY)
{
sprintf (tempBuff, filter, (theValue ? "T" : "F"));
}
else
{
sprintf (tempBuff, filter, (T) theValue);
}
lstrcat( (char*)rgbValue, tempBuff);
//Increment counter of number of bytes copied
(*pcbValue) += lstrlen (tempBuff);
}
}
}
else
{
//error !!!
//Tidy Up
delete tempBuff;
SafeArrayUnlock(pArray);
return ISAM_ERROR;
}
}
else
{
//No we don't so quit
//Tidy Up
delete tempBuff;
SafeArrayUnlock(pArray);
return ISAM_TRUNCATION;
}
loop++;
}
//Tidy Up
delete tempBuff;
SafeArrayUnlock(pArray);
return NO_ISAM_ERR;
}
/**************************************************************************/
SWORD INTFUNC ISAMGetArrayStringInfo (VARIANT &vVariantVal, BSTR syntaxStr,
PTR rgbValue, SDWORD cbValueMax, SDWORD FAR* pcbValue, BOOL fIsBinaryOutput, long myVirIndex)
{
//Check if we want all elements of the array or just one element
BOOL fAllElements = TRUE;
if (myVirIndex != -1)
{
fAllElements = FALSE;
}
//Get the value
SAFEARRAY FAR* pArray = vVariantVal.parray;
SafeArrayLock(pArray);
//Find out the bounds of the array
//Get the upper and lower bounds
long lLowerBound;
SafeArrayGetLBound(pArray, 1, &lLowerBound);
long lUpperBound;
SafeArrayGetUBound(pArray, 1, &lUpperBound);
*pcbValue = 0;
//Initialize
long cCount = 0;
BSTR theValue;
((char*)rgbValue)[0] = 0;
BOOL fOutOfBufferSpace = FALSE;
long loop = 0;
for (long cIndex = lLowerBound; (!fOutOfBufferSpace) && (cIndex <= lUpperBound); cIndex++)
{
//Check if we want to use this value
BOOL fUseThisValue = FALSE;
if (fAllElements)
{
fUseThisValue = TRUE;
}
else
{
if (loop == myVirIndex)
fUseThisValue = TRUE;
}
if (fUseThisValue)
{
if ( SUCCEEDED(SafeArrayGetElement(pArray, &cIndex, &theValue)) )
{
//Now we must add in string value in the format [string]
//However, if the string contains either [ or ] we must double
//this character in the string sequence
ULONG cLength = 0;
char* theValueStr = NULL;
if (theValue)
{
cLength = wcslen(theValue);
theValueStr = new char [cLength + 1];
theValueStr[0] = 0;
wcstombs(theValueStr, theValue, cLength);
theValueStr[cLength] = 0;
}
SWORD err = NO_ISAM_ERR;
if (!syntaxStr)
syntaxStr = L" ";
//Check if this is a string, timestamp, interval, time or date
BOOL foundMatch = FALSE;
// if ( (_wcsicmp(syntaxStr, WBEM_WSYNTAX_DATETIME) == 0) ||
// (_wcsicmp(syntaxStr, WBEM_WSYNTAX_INTERVAL) == 0))
if (_wcsicmp(syntaxStr, WBEM_WSYNTAX_DATETIME) == 0)
{
//A timestamp
DateTimeParser parser(theValue);
// if ( parser.IsValid() && parser.IsTimestamp() )
{
foundMatch = TRUE;
if (fIsBinaryOutput)
{
if (cbValueMax >= (SDWORD)((*pcbValue) + sizeof (TIMESTAMP_STRUCT)) )
{
TIMESTAMP_STRUCT FAR* pTimeStampStruct = (TIMESTAMP_STRUCT FAR*)((char*)rgbValue + (*pcbValue));
pTimeStampStruct->year = (SWORD)parser.GetYear();
pTimeStampStruct->month = (UWORD)parser.GetMonth();
pTimeStampStruct->day = (UWORD)parser.GetDay();
pTimeStampStruct->hour = (UWORD)parser.GetHour();
pTimeStampStruct->minute = (UWORD)parser.GetMin();
pTimeStampStruct->second = (UWORD)parser.GetSec();
pTimeStampStruct->fraction = 1000 * parser.GetMicroSec();
*pcbValue += sizeof (TIMESTAMP_STRUCT);
}
else
{
//not enough space
err = ISAM_TRUNCATION;
}
}
else
{
TIMESTAMP_STRUCT pTimeStampStruct;
pTimeStampStruct.year = (SWORD)parser.GetYear();
pTimeStampStruct.month = (UWORD)parser.GetMonth();
pTimeStampStruct.day = (UWORD)parser.GetDay();
pTimeStampStruct.hour = (UWORD)parser.GetHour();
pTimeStampStruct.minute = (UWORD)parser.GetMin();
pTimeStampStruct.second = (UWORD)parser.GetSec();
pTimeStampStruct.fraction = 1000 * parser.GetMicroSec();
if (fAllElements)
{
if (cbValueMax >= ( (*pcbValue) + 23+TIMESTAMP_SCALE) )
{
char szBuffer[20+TIMESTAMP_SCALE+1];
TimestampToChar(&pTimeStampStruct, (LPUSTR)szBuffer);
char* ptrToStr = ((char*)rgbValue + (*pcbValue));
sprintf (ptrToStr, "[%s]", szBuffer);
*pcbValue += (22+TIMESTAMP_SCALE); //ignore null
}
else
{
//not enough space
err = ISAM_TRUNCATION;
}
}
else
{
if (cbValueMax >= ( (*pcbValue) + 21+TIMESTAMP_SCALE) )
{
char szBuffer[20+TIMESTAMP_SCALE+1];
TimestampToChar(&pTimeStampStruct, (LPUSTR)szBuffer);
char* ptrToStr = ((char*)rgbValue + (*pcbValue));
sprintf (ptrToStr, "%s", szBuffer);
*pcbValue += (20+TIMESTAMP_SCALE); //ignore null
}
else
{
//not enough space
err = ISAM_TRUNCATION;
}
}
}
}
}
/*
else if (_wcsicmp(syntaxStr, WBEM_WSYNTAX_DATE) == 0)
{
//A date
DateTimeParser parser(theValue);
// if ( parser.IsValid() && parser.IsDate() )
{
foundMatch = TRUE;
if (fIsBinaryOutput)
{
if (cbValueMax >= (SDWORD)((*pcbValue) + sizeof (DATE_STRUCT)) )
{
DATE_STRUCT FAR* pDateStruct = (DATE_STRUCT FAR*)((char*)rgbValue + (*pcbValue));
pDateStruct->year = (SWORD)parser.GetYear();
pDateStruct->month = (UWORD)parser.GetMonth();
pDateStruct->day = (UWORD)parser.GetDay();
*pcbValue += sizeof (DATE_STRUCT);
}
else
{
//not enough space
err = ISAM_TRUNCATION;
}
}
else
{
DATE_STRUCT pDateStruct;
pDateStruct.year = (SWORD)parser.GetYear();
pDateStruct.month = (UWORD)parser.GetMonth();
pDateStruct.day = (UWORD)parser.GetDay();
if (cbValueMax >= ( (*pcbValue) + 3 + DATE_PRECISION) )
{
char szBuffer[DATE_PRECISION + 1];
DateToChar(&pDateStruct, szBuffer);
char* ptrToStr = ((char*)rgbValue + (*pcbValue));
sprintf (ptrToStr, "[%s]", szBuffer);
*pcbValue += (2 + DATE_PRECISION);// ignore null
}
else
{
//not enough space
err = ISAM_TRUNCATION;
}
}
}
}
else if (_wcsicmp(syntaxStr, WBEM_WSYNTAX_TIME) == 0)
{
//A time
DateTimeParser parser(theValue);
// if ( parser.IsValid() && parser.IsTime() )
{
foundMatch = TRUE;
if (fIsBinaryOutput)
{
if (cbValueMax >= (SDWORD)((*pcbValue) + sizeof (TIME_STRUCT)) )
{
TIME_STRUCT FAR* pTimeStruct = (TIME_STRUCT FAR*)((char*)rgbValue + (*pcbValue));
pTimeStruct->hour = (UWORD)parser.GetHour();
pTimeStruct->minute = (UWORD)parser.GetMin();
pTimeStruct->second = (UWORD)parser.GetSec();
*pcbValue += sizeof (TIME_STRUCT);
}
else
{
//not enough space
err = ISAM_TRUNCATION;
}
}
else
{
TIME_STRUCT pTimeStruct;
pTimeStruct.hour = (UWORD)parser.GetHour();
pTimeStruct.minute = (UWORD)parser.GetMin();
pTimeStruct.second = (UWORD)parser.GetSec();
if (cbValueMax >= ( (*pcbValue) + 3 + TIME_PRECISION) )
{
char szBuffer[TIME_PRECISION + 1];
TimeToChar(&pTimeStruct, szBuffer);
char* ptrToStr = ((char*)rgbValue + (*pcbValue));
sprintf (ptrToStr, "[%s]", szBuffer);
*pcbValue += (2 + TIME_PRECISION);//ignore null
}
else
{
//not enough space
err = ISAM_TRUNCATION;
}
}
}
}
*/
if (!foundMatch)
{
//Check if string or 64bit integer
SDWORD fInt64Check = 0;
if ( (_wcsicmp(syntaxStr, WBEM_WSYNTAX_SINT64) == 0) )
fInt64Check = WBEM_DSDT_SINT64;
if ( (_wcsicmp(syntaxStr, WBEM_WSYNTAX_UINT64) == 0) )
fInt64Check = WBEM_DSDT_UINT64;
err = ISAMFormatCharParm (theValueStr, fOutOfBufferSpace,
(char*)rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, fInt64Check, fAllElements);
}
if (theValue)
delete theValueStr;
//SAI MOVED
SysFreeString(theValue);
if (err != NO_ISAM_ERR)
{
SafeArrayUnlock(pArray);
return err;
}
}
else
{
//error !!!
SafeArrayUnlock(pArray);
return ISAM_ERROR;
}
}
loop++;
}
//Tidy Up
// SysFreeString(theValue);
SafeArrayUnlock(pArray);
return NO_ISAM_ERR;
}
/*
SWORD ISAMGetPropertyArrayInfo(BSTR & arrayVal,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue,
SWORD wbemVariantType,
BSTR syntaxStr,
BSTR maxStr)
{
SWORD err = NO_ISAM_ERR;
SWORD wDSDT = 0;
SWORD dummy1 = 0;
UDWORD cbPrecision = 0;
//Get the value
BSTR pString = arrayVal;
//If no WBEM variant type specified use default
if (!wbemVariantType)
wbemVariantType = WBEM_VARIANT_VT_ARRAY_BSTR;
//How do we want the value returned
switch (fCType)
{
case SQL_C_DOUBLE:
{
double dVal;
BOOL foundDecimalPoint;
BOOL isNull;
*pcbValue = sizeof(double);
if ((cbValueMax >= *pcbValue) &&
(DBASE_ERR_SUCCESS == ISAMGetDoubleFromString(pString, cbValueMax, dVal, isNull, foundDecimalPoint)) )
{
if (isNull)
{
*pcbValue = SQL_NULL_DATA;
}
else
{
*((double *)rgbValue) = dVal;
}
}
else
{
*pcbValue = 0;
return ERR_NOTCONVERTABLE;
}
}
break;
case SQL_C_CHAR:
{
char* pTemp = (char*) rgbValue;
pTemp[0] = 0;
*pcbValue = wcstombs( pTemp, pString, cbValueMax);
//Make an extra check here if you are requesting 64bit integers
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxStr, wDSDT, dummy1, cbPrecision);
//Check for numeric string
if ( (wDSDT == WBEM_DSDT_SINT64_ARRAY) )
{
for (SDWORD ii = 0; ii < (*pcbValue); ii++)
{
switch (pTemp[ii])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '+':
case '-':
//OK
break;
default:
return ERR_INVALID_INTEGER;
break;
}
}
}
if ( (wDSDT == WBEM_DSDT_UINT64_ARRAY) )
{
for (SDWORD ii = 0; ii < (*pcbValue); ii++)
{
switch (pTemp[ii])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
//OK
break;
default:
return ERR_INVALID_INTEGER;
break;
}
}
}
}
break;
case SQL_C_TIMESTAMP:
{
//Check that you have enough buffer to store value
*pcbValue = sizeof (TIMESTAMP_STRUCT);
TIMESTAMP_STRUCT FAR* pTimeStampStruct = (TIMESTAMP_STRUCT FAR*)rgbValue;
if ( cbValueMax >= (*pcbValue) )
{
DateTimeParser parser(pString);
// if ( parser.IsValid() && parser.IsTimestamp() )
{
pTimeStampStruct->year = (SWORD)parser.GetYear();
pTimeStampStruct->month = (UWORD)parser.GetMonth();
pTimeStampStruct->day = (UWORD)parser.GetDay();
pTimeStampStruct->hour = (UWORD)parser.GetHour();
pTimeStampStruct->minute = (UWORD)parser.GetMin();
pTimeStampStruct->second = (UWORD)parser.GetSec();
pTimeStampStruct->fraction = 1000 * parser.GetMicroSec();
}
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
break;
case SQL_C_BINARY:
default:
{
//No convertion available
return ERR_NOTCONVERTABLE;
}
break;
}
return err;
}
*/
/***************************************************************************/
/* Retrieves the value from a variant */
SWORD ISAMGet_VT_I2(short iShortVal,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue,
SWORD wbemVariantType,
BSTR syntaxStr,
SDWORD maxLenVal)
{
SWORD err = NO_ISAM_ERR;
SWORD wDSDT = 0;
SWORD dummy1 = 0;
UDWORD cbPrecision = 0;
//If no WBEM variant type specified use default
if (!wbemVariantType)
wbemVariantType = WBEM_VARIANT_VT_I2;
//How do we want the value returned
switch (fCType)
{
case SQL_C_DOUBLE:
{
//Check that you have enough buffer to store value
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
if ( (wDSDT == WBEM_DSDT_SINT8) || (wDSDT == WBEM_DSDT_SINT8_ARRAY) )
{
//Signed 8 bit value
//Check that you have enough buffer to store value
*pcbValue = sizeof(signed char);
if (cbValueMax >= *pcbValue)
{
signed char iCharVal = (signed char) iShortVal;
*((double *)rgbValue) = (double)iCharVal;
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
else
{
//Signed 16 bit value
//Check that you have enough buffer to store value
*pcbValue = sizeof(double);
if (cbValueMax >= *pcbValue)
{
*((double *)rgbValue) = (double)iShortVal;
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
}
break;
case SQL_C_CHAR:
{
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
if ( (wDSDT == WBEM_DSDT_SINT8) || (wDSDT == WBEM_DSDT_SINT8_ARRAY) )
{
//Signed 8 bit value
//Check that there is enough buffer space for largest value
if (cbValueMax >= STINYINT_PRECISION)
{
char ttt = (char) iShortVal;
char* pTemp = (char*)rgbValue;
pTemp[0] = 0;
sprintf ((char*)rgbValue, "%d", (short)ttt);
*pcbValue = lstrlen(pTemp);
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
else
{
//Signed 16 bit value
//Check that there is enough buffer space for largest value
if (cbValueMax >= SSHORT_PRECISION)
{
char* pTemp = (char*)rgbValue;
pTemp[0] = 0;
sprintf ((char*)rgbValue, "%ld", iShortVal);
*pcbValue = lstrlen(pTemp);
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
}
break;
case SQL_C_DATE:
case SQL_C_TIME:
case SQL_C_TIMESTAMP:
case SQL_C_BINARY:
default:
{
//No convertion available
return ISAM_ERROR;
}
break;
}
return err;
}
SWORD ISAMGet_VT_UI1(UCHAR iUcharVal,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue,
SWORD wbemVariantType,
BSTR syntaxStr,
SDWORD maxLenVal)
{
SWORD err = NO_ISAM_ERR;
SWORD wDSDT = 0;
SWORD dummy1 = 0;
UDWORD cbPrecision = 0;
//If no WBEM variant type specified use default
if (!wbemVariantType)
wbemVariantType = WBEM_VARIANT_VT_UI1;
//How do we want the value returned
switch (fCType)
{
case SQL_C_DOUBLE:
{
*pcbValue = sizeof(double);
//Check that you have enough buffer to store value
if (cbValueMax >= *pcbValue)
{
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
{
//Unsigned 8 bit value
*((double *)rgbValue) = (double)iUcharVal;
}
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
break;
case SQL_C_CHAR:
{
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
if (cbValueMax >= UTINYINT_PRECISION)
{
//Unsigned 8 bit value
//Check that there is enough buffer space for largest value
char* pTemp = (char*)rgbValue;
pTemp[0] = 0;
_itoa(iUcharVal, pTemp, 10);
*pcbValue = lstrlen(pTemp);
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
break;
case SQL_C_DATE:
case SQL_C_TIME:
case SQL_C_TIMESTAMP:
case SQL_C_BINARY:
default:
{
//No convertion available
return ERR_NOTCONVERTABLE;
}
break;
}
return err;
}
SWORD ISAMGet_VT_I4(long iValue,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue,
SWORD wbemVariantType,
BSTR syntaxStr,
SDWORD maxLenVal)
{
SWORD err = NO_ISAM_ERR;
SWORD wDSDT = 0;
SWORD dummy1 = 0;
UDWORD cbPrecision = 0;
//If no WBEM variant type specified use default
if (!wbemVariantType)
wbemVariantType = WBEM_VARIANT_VT_I4;
//How do we want the value returned
switch (fCType)
{
case SQL_C_DOUBLE:
{
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
*pcbValue = sizeof (double);
if ( (wDSDT == WBEM_DSDT_UINT16) || (wDSDT == WBEM_DSDT_UINT16_ARRAY) )
{
//Unsigned 16 bit value
//Check that there is enough buffer space for largest value
if (cbValueMax >= *pcbValue)
{
double dd = (unsigned short) iValue;
*((double *)rgbValue) = dd;
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
else if ( (wDSDT == WBEM_DSDT_UINT32) || (wDSDT == WBEM_DSDT_UINT32_ARRAY) )
{
//Unsigned 32 bit value
//Check that you have enough buffer to store value
*pcbValue = sizeof (double);
if (cbValueMax >= *pcbValue)
{
double dd = (unsigned long) iValue;
*((double *)rgbValue) = dd;
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
else
{
//Signed 32 bit value
//Check that you have enough buffer to store value
if (cbValueMax >= *pcbValue)
{
*((double *)rgbValue) = (double)iValue;
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
}
break;
case SQL_C_CHAR:
{
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
if ( (wDSDT == WBEM_DSDT_UINT16) || (wDSDT == WBEM_DSDT_UINT16_ARRAY) )
{
//Unsigned 16 bit value
//Check that there is enough buffer space for largest value
if (cbValueMax >= USHORT_PRECISION)
{
unsigned short iushort = (unsigned short) iValue;
char* pTemp = (char*)rgbValue;
pTemp[0] = 0;
sprintf ((char*)rgbValue, "%lu", iushort);
*pcbValue = lstrlen(pTemp);
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
else if ( (wDSDT == WBEM_DSDT_UINT32) || (wDSDT == WBEM_DSDT_UINT32_ARRAY) )
{
//Unsigned 32 bit value
//Check that there is enough buffer space for largest value
if (cbValueMax >= ULONG_PRECISION)
{
unsigned long iulong = (unsigned long) iValue;
char* pTemp = (char*)rgbValue;
pTemp[0] = 0;
sprintf ((char*)rgbValue, "%lu", iulong);
*pcbValue = lstrlen(pTemp);
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
else
{
//Signed 32 bit value
//Check that there is enough buffer space for largest value
if (cbValueMax >= SLONG_PRECISION)
{
char* pTemp = (char*)rgbValue;
pTemp[0] = 0;
sprintf ((char*)rgbValue, "%ld", iValue);
*pcbValue = lstrlen(pTemp);
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
}
break;
case SQL_C_DATE:
case SQL_C_TIME:
case SQL_C_TIMESTAMP:
case SQL_C_BINARY:
default:
{
//No convertion available
return ERR_NOTCONVERTABLE;
}
break;
}
return err;
}
SWORD ISAMGet_VT_BOOL(VARIANT_BOOL fBool,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue,
SWORD wbemVariantType,
BSTR syntaxStr,
SDWORD maxLenVal)
{
SWORD err = NO_ISAM_ERR;
SWORD wDSDT = 0;
SWORD dummy1 = 0;
UDWORD cbPrecision = 0;
//How do we want the value returned
switch (fCType)
{
case SQL_C_DOUBLE:
{
*pcbValue = sizeof(double);
//Check that you have enough buffer to store value
if (cbValueMax >= *pcbValue)
{
if (fBool)
*((double *)rgbValue) = 1.0;
else
*((double *)rgbValue) = 0.0;
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
break;
case SQL_C_CHAR:
{
if (cbValueMax)
{
char* pTemp = (char*)rgbValue;
pTemp[0] = 0;
if (fBool)
lstrcpy(pTemp, "T");
else
lstrcpy(pTemp, "F");
*pcbValue = 1;
}
}
break;
case SQL_C_DATE:
case SQL_C_TIME:
case SQL_C_TIMESTAMP:
case SQL_C_BINARY:
default:
{
//No convertion available
return ERR_NOTCONVERTABLE;
}
break;
}
return err;
}
SWORD ISAMGet_VT_R4(float fltVal,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue,
SWORD wbemVariantType,
BSTR syntaxStr,
SDWORD maxLenVal)
{
SWORD err = NO_ISAM_ERR;
SWORD wDSDT = 0;
SWORD dummy1 = 0;
UDWORD cbPrecision = 0;
//How do we want the value returned
switch (fCType)
{
case SQL_C_DOUBLE:
{
*pcbValue = sizeof(double);
//Check that you have enough buffer to store value
if (cbValueMax >= *pcbValue)
{
*((double *)rgbValue) = (double)fltVal;
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
break;
case SQL_C_CHAR:
{
int decimal, sign;
double dblVal = fltVal;
char* buffer = _ecvt(dblVal, cbValueMax - 2, &decimal, &sign);
char* pTemp = (char*) rgbValue;
pTemp[0] = 0;
//We need a buffer to store at least "-.3"
if (cbValueMax < 3)
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
//Check if value is negative
if (sign)
{
strcpy(pTemp, "-");
}
//Now copy digits BEFORE the decimal point
if (cbValueMax && decimal)
{
strncat(pTemp, buffer, decimal);
}
char* pt = buffer + decimal;
if (cbValueMax && strlen (pt) )
{
//Add the decimal point
strcat (pTemp, ".");
//Copy digits AFTER decimal point
strcat(pTemp, pt);
}
*pcbValue = strlen (pTemp);
}
break;
case SQL_C_DATE:
case SQL_C_TIME:
case SQL_C_TIMESTAMP:
case SQL_C_BINARY:
default:
{
//No convertion available
return ERR_NOTCONVERTABLE;
}
break;
}
return err;
}
SWORD ISAMGet_VT_R8(double dblVal,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue,
SWORD wbemVariantType,
BSTR syntaxStr,
SDWORD maxLenVal)
{
SWORD err = NO_ISAM_ERR;
SWORD wDSDT = 0;
SWORD dummy1 = 0;
UDWORD cbPrecision = 0;
//How do we want the value returned
switch (fCType)
{
case SQL_C_DOUBLE:
case SQL_C_DEFAULT:
{
*pcbValue = sizeof(double);
//Check that you have enough buffer to store value
if (cbValueMax >= *pcbValue)
{
*((double *)rgbValue) = (double)dblVal;
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
break;
case SQL_C_CHAR:
{
int decimal, sign;
char* buffer = _ecvt(dblVal, cbValueMax - 2, &decimal, &sign);
char* pTemp = (char*) rgbValue;
pTemp[0] = 0;
//We need a buffer to store at least "-.3"
if (cbValueMax < 3)
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
//Check if value is negative
if (sign)
{
strcpy(pTemp, "-");
}
//Now copy digits BEFORE the decimal point
if (cbValueMax && decimal)
{
strncat(pTemp, buffer, decimal);
}
char* pt = buffer + decimal;
if (cbValueMax && strlen (pt) )
{
//Add the decimal point
strcat (pTemp, ".");
//Copy digits AFTER decimal point
strcat(pTemp, pt);
}
*pcbValue = strlen (pTemp);
}
break;
case SQL_C_DATE:
case SQL_C_TIME:
case SQL_C_TIMESTAMP:
case SQL_C_BINARY:
default:
{
//No convertion available
return ERR_NOTCONVERTABLE;
}
break;
}
return err;
}
SWORD ISAMGet_VT_BSTR(BSTR pString,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue,
SWORD wbemVariantType,
BSTR syntaxStr,
SDWORD maxLenVal)
{
SWORD err = NO_ISAM_ERR;
SWORD wDSDT = 0;
SWORD dummy1 = 0;
UDWORD cbPrecision = 0;
//If no WBEM variant type specified use default
if (!wbemVariantType)
wbemVariantType = WBEM_VARIANT_VT_BSTR;
//How do we want the value returned
switch (fCType)
{
case SQL_C_DOUBLE:
{
double dVal;
BOOL foundDecimalPoint;
BOOL isNull;
*pcbValue = sizeof(double);
if ((cbValueMax >= *pcbValue) &&
(DBASE_ERR_SUCCESS == ISAMGetDoubleFromString(pString, cbValueMax, dVal, isNull, foundDecimalPoint)) )
{
if (isNull)
{
*pcbValue = SQL_NULL_DATA;
}
else
{
*((double *)rgbValue) = dVal;
}
}
else
{
*pcbValue = 0;
return ERR_NOTCONVERTABLE;
}
}
break;
case SQL_C_CHAR:
{
char* pTemp = (char*) rgbValue;
_bstr_t myValue((BSTR)pString);
*pcbValue = Utility_WideCharToDBCS(myValue, &pTemp, cbValueMax);
//Make an extra check here if you are requesting 64bit integers
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
//Check for numeric string
if ( (wDSDT == WBEM_DSDT_SINT64) )
{
for (SDWORD ii = 0; ii < (*pcbValue); ii++)
{
switch (pTemp[ii])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '+':
case '-':
//OK
break;
default:
return ERR_INVALID_INTEGER;
break;
}
}
}
if ( (wDSDT == WBEM_DSDT_UINT64) )
{
for (SDWORD ii = 0; ii < (*pcbValue); ii++)
{
switch (pTemp[ii])
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
//OK
break;
default:
return ERR_INVALID_INTEGER;
break;
}
}
}
}
break;
/*
case SQL_C_DATE:
{
//Check that you have enough buffer to store value
*pcbValue = sizeof (DATE_STRUCT);
DATE_STRUCT FAR* pDateStruct = (DATE_STRUCT FAR*)rgbValue;
if ( cbValueMax >= (*pcbValue) )
{
DateTimeParser parser(pString);
// if ( parser.IsValid() && parser.IsDate() )
{
pDateStruct->year = (SWORD)parser.GetYear();
pDateStruct->month = (UWORD)parser.GetMonth();
pDateStruct->day = (UWORD)parser.GetDay();
}
// else
// {
// *pcbValue = 0;
// return ERR_INVALID_DATE;
// }
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
break;
case SQL_C_TIME:
{
//Check that you have enough buffer to store value
*pcbValue = sizeof (TIME_STRUCT);
TIME_STRUCT FAR* pTimeStruct = (TIME_STRUCT FAR*)rgbValue;
if ( cbValueMax >= (*pcbValue) )
{
DateTimeParser parser(pString);
// if ( parser.IsValid() && parser.IsTime() )
{
pTimeStruct->hour = (UWORD)parser.GetHour();
pTimeStruct->minute = (UWORD)parser.GetMin();
pTimeStruct->second = (UWORD)parser.GetSec();
}
// else
// {
// *pcbValue = 0;
// return ERR_INVALID_TIME;
// }
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
break;
*/
case SQL_C_TIMESTAMP:
{
//Check that you have enough buffer to store value
*pcbValue = sizeof (TIMESTAMP_STRUCT);
TIMESTAMP_STRUCT FAR* pTimeStampStruct = (TIMESTAMP_STRUCT FAR*)rgbValue;
if ( cbValueMax >= (*pcbValue) )
{
DateTimeParser parser(pString);
// if ( parser.IsValid() && parser.IsTimestamp() )
{
pTimeStampStruct->year = (SWORD)parser.GetYear();
pTimeStampStruct->month = (UWORD)parser.GetMonth();
pTimeStampStruct->day = (UWORD)parser.GetDay();
pTimeStampStruct->hour = (UWORD)parser.GetHour();
pTimeStampStruct->minute = (UWORD)parser.GetMin();
pTimeStampStruct->second = (UWORD)parser.GetSec();
pTimeStampStruct->fraction = 1000 * parser.GetMicroSec();
}
// else
// {
// *pcbValue = 0;
// return ERR_INVALID_TIMESTAMP;
// }
}
else
{
*pcbValue = 0;
return ERR_INSUFF_BUFFER;
}
}
break;
case SQL_C_BINARY:
default:
{
//No convertion available
return ERR_NOTCONVERTABLE;
}
break;
}
return err;
}
SWORD ISAMGetValueFromVariant(VARIANT &vVariantVal,
SWORD fCType,
PTR rgbValue,
SDWORD cbValueMax,
SDWORD FAR *pcbValue,
SWORD wbemVariantType,
BSTR syntaxStr,
SDWORD maxLenVal,
long myVirIndex)
{
SWORD err = NO_ISAM_ERR;
SWORD wDSDT = 0;
SWORD dummy1 = 0;
UDWORD cbPrecision = 0;
VARTYPE varType1 = V_VT(&vVariantVal);
switch( varType1 )
{
case VT_NULL:
{
*pcbValue = SQL_NULL_DATA;
}
break;
case VT_I2:
{
//Get the value
short iShortVal = vVariantVal.iVal;
err = ISAMGet_VT_I2(iShortVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
}
break;
case VT_I4:
{
//Get the value
long iValue = vVariantVal.lVal;
err = ISAMGet_VT_I4(iValue,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
}
break;
case VT_UI1:
{
//Get the value
UCHAR iUcharVal = vVariantVal.bVal;
err = ISAMGet_VT_UI1(iUcharVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
}
break;
case VT_BSTR:
{
//Get the value
BSTR pString = vVariantVal.bstrVal;
err = ISAMGet_VT_BSTR(pString,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
//Null terminate this string
if (cbValueMax > *pcbValue)
{
((char*)rgbValue)[*pcbValue] = '\0';
// ODBCTRACE (_T("Null terminating this string"));
}
else
{
// ODBCTRACE (_T("Not Null terminating this string"));
}
}
break;
case VT_R8:
{
//Get the value
double dblVal = vVariantVal.dblVal;
err = ISAMGet_VT_R8(dblVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
}
break;
case VT_R4:
{
//Get the value
float fltVal = vVariantVal.fltVal;
err = ISAMGet_VT_R4(fltVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
}
break;
case VT_BOOL:
{
//Get the value
VARIANT_BOOL fBool = vVariantVal.boolVal;
err = ISAMGet_VT_BOOL(fBool,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
}
break;
default:
{
//Before we quit, check whether it is a VT_ARRAY
BOOL fIsVT_ARRAY = FALSE;
SWORD wStatus = ISAM_ERROR;
BOOL fIsBinaryOutput = (fCType == SQL_C_BINARY);
if ( varType1 == (VT_ARRAY|VT_UI1 ))
{
//If no WBEM variant type specified use default
if (!wbemVariantType)
wbemVariantType = WBEM_VARIANT_VT_ARRAY_UI1;
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
//Get the precision for a single item in array
{
UCHAR ubVal = 0;
cbPrecision = UTINYINT_PRECISION;
if (myVirIndex == -1)
{
//String display for all elements
wStatus = ISAMGetArrayInfo (vVariantVal, ubVal,
rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
}
else
{
//others
SAFEARRAY FAR* pArray = vVariantVal.parray;
if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &ubVal)) )
{
err = ISAMGet_VT_UI1(ubVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
wStatus = NO_ISAM_ERR;
if (err == ERR_INSUFF_BUFFER)
wStatus = ISAM_TRUNCATION;
if (err == ISAM_ERROR)
wStatus = ISAM_ERROR;
}
}
}
}
else if (( varType1 == (VT_ARRAY|VT_I4)))
{
//If no WBEM variant type specified use default
if (!wbemVariantType)
wbemVariantType = WBEM_VARIANT_VT_ARRAY_I4;
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
//Get the precision for a single item in array
if (wDSDT == WBEM_DSDT_UINT16_ARRAY)
{
USHORT wVal = 0;
cbPrecision = SMALLINT_PRECISION;
if (myVirIndex == -1)
{
//String display for all elements
wStatus = ISAMGetArrayInfo (vVariantVal, wVal,
rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
}
else
{
//others
SAFEARRAY FAR* pArray = vVariantVal.parray;
if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &wVal)) )
{
err = ISAMGet_VT_I4(wVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
wStatus = NO_ISAM_ERR;
if (err == ERR_INSUFF_BUFFER)
wStatus = ISAM_TRUNCATION;
if (err == ISAM_ERROR)
wStatus = ISAM_ERROR;
}
}
}
else if (wDSDT == WBEM_DSDT_UINT32_ARRAY)
{
ULONG lValue = 0;
cbPrecision = ULONG_PRECISION;
if (myVirIndex == -1)
{
//String display for all elements
wStatus = ISAMGetArrayInfo (vVariantVal, lValue,
rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
}
else
{
//others
SAFEARRAY FAR* pArray = vVariantVal.parray;
if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &lValue)) )
{
err = ISAMGet_VT_I4(lValue,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
wStatus = NO_ISAM_ERR;
if (err == ERR_INSUFF_BUFFER)
wStatus = ISAM_TRUNCATION;
if (err == ISAM_ERROR)
wStatus = ISAM_ERROR;
}
}
}
else
{
//SINT32
long lValue = 0;
cbPrecision = ULONG_PRECISION + 1;
if (myVirIndex == -1)
{
//String display for all elements
wStatus = ISAMGetArrayInfo (vVariantVal, lValue,
rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
}
else
{
//others
SAFEARRAY FAR* pArray = vVariantVal.parray;
if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &lValue)) )
{
err = ISAMGet_VT_I4(lValue,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
wStatus = NO_ISAM_ERR;
if (err == ERR_INSUFF_BUFFER)
wStatus = ISAM_TRUNCATION;
if (err == ISAM_ERROR)
wStatus = ISAM_ERROR;
}
}
}
}
else if ((varType1 == (VT_ARRAY|VT_BOOL)))
{
BOOL fBoolVal = TRUE;
wDSDT = WBEM_DSDT_BOOL_ARRAY;
cbPrecision = 1;
if (myVirIndex == -1)
{
//String display for all elements
wStatus = ISAMGetArrayInfo (vVariantVal, fBoolVal,
rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
}
else
{
//others
SAFEARRAY FAR* pArray = vVariantVal.parray;
if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &fBoolVal)) )
{
err = ISAMGet_VT_BOOL((VARIANT_BOOL) fBoolVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
wStatus = NO_ISAM_ERR;
if (err == ERR_INSUFF_BUFFER)
wStatus = ISAM_TRUNCATION;
if (err == ISAM_ERROR)
wStatus = ISAM_ERROR;
}
}
}
else if ((varType1 == (VT_ARRAY|VT_I2)))
{
short wVal = 0;
//If no WBEM variant type specified use default
if (!wbemVariantType)
wbemVariantType = WBEM_VARIANT_VT_ARRAY_I2;
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
//Get the precision for a single item in array
if (wDSDT == WBEM_DSDT_SINT8_ARRAY)
{
//char bVal = 0;
short bVal = 0;
cbPrecision = UTINYINT_PRECISION + 1;
if (myVirIndex == -1)
{
//String display for all elements
wStatus = ISAMGetArrayInfo (vVariantVal, bVal,
rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
}
else
{
//others
SAFEARRAY FAR* pArray = vVariantVal.parray;
if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &bVal)) )
{
err = ISAMGet_VT_I2(bVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
wStatus = NO_ISAM_ERR;
if (err == ERR_INSUFF_BUFFER)
wStatus = ISAM_TRUNCATION;
if (err == ISAM_ERROR)
wStatus = ISAM_ERROR;
}
}
}
else if (wDSDT == WBEM_DSDT_SINT16_ARRAY)
{
short wVal = 0;
cbPrecision = SMALLINT_PRECISION + 1;
if (myVirIndex == -1)
{
//String display for all elements
wStatus = ISAMGetArrayInfo (vVariantVal, wVal,
rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
}
else
{
//others
SAFEARRAY FAR* pArray = vVariantVal.parray;
if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &wVal)) )
{
err = ISAMGet_VT_I2(wVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
wStatus = NO_ISAM_ERR;
if (err == ERR_INSUFF_BUFFER)
wStatus = ISAM_TRUNCATION;
if (err == ISAM_ERROR)
wStatus = ISAM_ERROR;
}
}
}
}
else if ((varType1 == (VT_ARRAY|VT_R4)))
{
float fltVal = (float)0.0;
//If no WBEM variant type specified use default
if (!wbemVariantType)
wbemVariantType = WBEM_VARIANT_VT_ARRAY_R4;
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
if (myVirIndex == -1)
{
//String display for all elements
wStatus = ISAMGetArrayInfo (vVariantVal, fltVal,
rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
}
else
{
//others
SAFEARRAY FAR* pArray = vVariantVal.parray;
if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &fltVal)) )
{
err = ISAMGet_VT_R4(fltVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
wStatus = NO_ISAM_ERR;
if (err == ERR_INSUFF_BUFFER)
wStatus = ISAM_TRUNCATION;
if (err == ISAM_ERROR)
wStatus = ISAM_ERROR;
}
}
}
else if ((varType1 == (VT_ARRAY|VT_R8)))
{
double dblVal = 0;
//If no WBEM variant type specified use default
if (!wbemVariantType)
wbemVariantType = WBEM_VARIANT_VT_ARRAY_R8;
ISAMGetDataSourceDependantTypeInfo
((SWORD)wbemVariantType, syntaxStr, maxLenVal, wDSDT, dummy1, cbPrecision);
if (myVirIndex == -1)
{
//String display for all elements
wStatus = ISAMGetArrayInfo (vVariantVal, dblVal,
rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, wDSDT, cbPrecision, myVirIndex);
}
else
{
//others
SAFEARRAY FAR* pArray = vVariantVal.parray;
if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &dblVal)) )
{
err = ISAMGet_VT_R8(dblVal,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
wStatus = NO_ISAM_ERR;
if (err == ERR_INSUFF_BUFFER)
wStatus = ISAM_TRUNCATION;
if (err == ISAM_ERROR)
wStatus = ISAM_ERROR;
}
}
}
else if ((varType1 == (VT_ARRAY|VT_BSTR)))
{
if (myVirIndex == -1)
{
//String display for all elements
wStatus = ISAMGetArrayStringInfo (vVariantVal, syntaxStr,
rgbValue, cbValueMax, pcbValue, fIsBinaryOutput, myVirIndex);
}
else
{
//others
BSTR pString = NULL;
SAFEARRAY FAR* pArray = vVariantVal.parray;
if ( SUCCEEDED(SafeArrayGetElement(pArray, &myVirIndex, &pString)) )
{
err = ISAMGet_VT_BSTR(pString,
fCType,
rgbValue,
cbValueMax,
pcbValue,
wbemVariantType,
syntaxStr,
maxLenVal
);
wStatus = NO_ISAM_ERR;
if (err == ERR_INSUFF_BUFFER)
wStatus = ISAM_TRUNCATION;
if (err == ISAM_ERROR)
wStatus = ISAM_ERROR;
//SAI ADDED
SysFreeString(pString);
}
}
if (wStatus == NO_ISAM_ERR)
{
//Null terminate this string
if (cbValueMax > *pcbValue)
{
((char*)rgbValue)[*pcbValue] = '\0';
// ODBCTRACE (_T("Null terminating this string"));
}
else
{
// ODBCTRACE (_T("Not Null terminating this string"));
}
}
}
if (wStatus == ISAM_TRUNCATION)
{
//Truncated data
return ISAM_TRUNCATION;
}
else if (wStatus != NO_ISAM_ERR)
{
//No convertion available
return wStatus;
}
}
break;
}
return err;
}
/***************************************************************************/
// Checked for SetInterfaceSecurityEx on IWbemServices and IEnumWbemClassObject
IMPLEMENT_SERIAL (CNamespace, CObject, 1)
SWORD INTFUNC ISAMGetNestedNamespaces (char *parentName, char *namespaceName,
IWbemServices *pGatewayIn,
DWORD dwAuthLevelIn, DWORD dwImpLevelIn,
char *servername,
// WBEM_LOGIN_AUTHENTICATION loginMethod,
char *username, char *password, BOOL fIntpretEmptPwdAsBlank,
char* locale, char* authority,
CMapStringToOb* map, BOOL bDeep)
{
// Always want to return absolute names here
char *absName = NULL;
IWbemServicesPtr pGateway;
DWORD dwAuthLevel = 0;
DWORD dwImpLevel = 0;
COAUTHIDENTITY* pAuthIdent = NULL;
if (NULL == pGatewayIn)
{
pGateway = NULL;
ISAMGetGatewayServer (pGateway,
(LPUSTR)servername,
// loginMethod,
(LPUSTR)namespaceName, (LPUSTR)username, (LPUSTR)password, (LPUSTR)locale, (LPUSTR)authority,
dwAuthLevel, dwImpLevel, fIntpretEmptPwdAsBlank , &pAuthIdent);
if (pGateway == NULL)
return ISAM_ERROR;
// the passed in name is absolute
absName = new char [strlen (namespaceName) +1];
absName[0] = 0;
strcpy (absName, namespaceName);
map->SetAt (absName, new CNamespace (absName)); // add self
}
else
{
pGateway = pGatewayIn;
pGateway->AddRef ();
dwAuthLevel = dwAuthLevelIn;
dwImpLevel = dwImpLevelIn;
// the passed in name is relative - so build absolute - and add to map
absName = new char [strlen (parentName) + strlen(namespaceName) + 2
+ 1 /* for separator */];
absName[0] = 0;
strcpy (absName, parentName);
strcat (absName, "\\"); // add separator
strcat (absName, namespaceName);
map->SetAt (absName, new CNamespace (absName));
}
if (!bDeep)
{
delete absName;
return NO_ISAM_ERR;
}
//cloaking
BOOL fIsLocalConnection = IsLocalServer(servername);
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(pGateway, dwAuthLevel, dwImpLevel);
}
//Enumerate children and recurse
IEnumWbemClassObject* pNamespaceEnum = NULL;
BSTR nspaceBSTR = SysAllocString(WBEMDR32_L_NAMESPACE);
IWbemContext* pContext = ISAMCreateLocaleIDContextObject(locale);
if ( FAILED(pGateway->CreateInstanceEnum(nspaceBSTR, 0, pContext, &pNamespaceEnum)) )
{
delete absName;
SysFreeString(nspaceBSTR);
if (pContext)
pContext->Release();
//Should be not also Release pGateway ?
return NO_ISAM_ERR;
}
else
{
ISAMSetCloaking2(pNamespaceEnum,
fIsLocalConnection,
IsW2KOrMore(),
dwAuthLevel,
dwImpLevel,
pAuthIdent);
/*
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(pNamespaceEnum, dwAuthLevel, dwImpLevel);
}
else
{
//Set Dcom blanket
SetInterfaceSecurityEx(pNamespaceEnum, pAuthIdent, gpPrincipal, dwAuthLevel, dwImpLevel);
}
*/
SysFreeString(nspaceBSTR);
if (pContext)
pContext->Release();
if (!pNamespaceEnum)
{
delete absName;
return NO_ISAM_ERR;
}
ULONG uRet = 0;
IWbemClassObject* pNewInst = NULL;
pNamespaceEnum->Reset();
while ( S_OK == pNamespaceEnum->Next(-1, 1, &pNewInst, &uRet) )
{
VARIANTARG var;
//SAI ADDED no need to init VariantInit (&var);
BSTR nameBSTR = SysAllocString(WBEMDR32_L_NAME);
pNewInst->Get(nameBSTR, 0, &var, NULL, NULL);
SysFreeString(nameBSTR);
IWbemServicesPtr pNewGateway = NULL;
COAUTHIDENTITY* pNewAuthIdent = NULL;
//Get user and password fields
#ifdef USING_ABSPATH
char testBuff [MAX_QUALIFIER_NAME_LENGTH + 1];
testBuff[0] = 0;
wcstombs(testBuff, var.bstrVal, MAX_QUALIFIER_NAME_LENGTH);
testBuff[MAX_QUALIFIER_NAME_LENGTH] = 0;
char* cTemp2 = new char [strlen (absName) + strlen(testBuff) + 2];
cTemp2[0] = 0;
lstrcpy(cTemp2,absName);
lstrcat(cTemp2, "\\");
lstrcat(cTemp2,testBuff);
ISAMGetGatewayServer (pNewGateway, servername,
// loginMethod,
cTemp2, username, password, locale, authority, &pNewAuthIdent);
delete cTemp2;
if (pNewGateway)
#else
BSTR myRelativeNamespace = var.bstrVal;
CBString cbNS (myRelativeNamespace, FALSE);
IWbemContext* mycontext = ISAMCreateLocaleIDContextObject(locale);
if ( SUCCEEDED(pGateway->OpenNamespace(cbNS.GetString(), 0, mycontext, &pNewGateway, NULL)) )
#endif
{
BOOL fIsLocalConnection = IsLocalServer(servername);
ISAMSetCloaking2(pNewGateway,
fIsLocalConnection,
IsW2KOrMore(),
dwAuthLevel,
dwImpLevel,
pNewAuthIdent);
/*
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(pNewGateway, dwAuthLevel, dwImpLevel);
}
else
{
//Set Dcom blanket
SetInterfaceSecurityEx(pNewGateway, pNewAuthIdent, gpPrincipal, dwAuthLevel, dwImpLevel);
}
*/
size_t len = wcstombs (NULL, var.bstrVal, MB_CUR_MAX);
if (-1 != len)
{
char *name = new char [len + 1];
name[0] = 0;
wcstombs (name, var.bstrVal, len);
name [len] = 0;
ISAMGetNestedNamespaces (absName, name, pNewGateway, dwAuthLevel, dwImpLevel, servername,
// loginMethod,
username, password, fIntpretEmptPwdAsBlank, locale, authority, map);
delete name;
}
if (pNewAuthIdent)
{
WbemFreeAuthIdentity( pNewAuthIdent );
pNewAuthIdent = NULL;
}
}
#ifndef USING_ABSPATH
if (mycontext)
mycontext->Release();
#endif
VariantClear(&var);
}
//Tidy Up
if (pNamespaceEnum)
{
pNamespaceEnum->Release();
}
}
delete absName;
if (pAuthIdent )
{
WbemFreeAuthIdentity( pAuthIdent );
pAuthIdent = NULL;
}
return NO_ISAM_ERR;
}
/***************************************************************************/
SWORD INTFUNC ISAMBuildTree (HTREEITEM hParent,
char *namespaceName, //relative name
CTreeCtrl& treeCtrl,
CConnectionDialog& dialog,
char *server,
// WBEM_LOGIN_AUTHENTICATION loginMethod,
char *username,
char *password,
BOOL fIntpretEmptPwdAsBlank,
char *locale,
char *authority,
BOOL fNeedChildren,
BOOL deep,
HTREEITEM& hTreeItem)
{
// Note the first name in the tree will be displayed as absolute
// could strip off the non- root bit - might do it
ODBCTRACE ("\nWBEM ODBC Driver :ISAMBuildTree\n");
// Add self
hTreeItem = dialog.InsertItem(treeCtrl, hParent, namespaceName);
ODBCTRACE ("\nWBEM ODBC Driver :Add Self :");
ODBCTRACE (namespaceName);
ODBCTRACE ("\n");
//Enumerate children and recurse
//BUT ONLY IF REQUESTED
if (fNeedChildren)
{
ODBCTRACE ("\nWBEM ODBC Driver : fNeedChildren = TRUE\n");
//Work out absolute name of new namespace
TV_ITEM tvItem2;
tvItem2.hItem = hTreeItem;
tvItem2.mask = TVIF_PARAM;
if (treeCtrl.GetItem (&tvItem2))
{
char* txt = ((ISAMTreeItemData*)tvItem2.lParam)->absName;
return ISAMBuildTreeChildren(hTreeItem, txt, treeCtrl, dialog,
server,
// loginMethod,
username, password, fIntpretEmptPwdAsBlank,locale, authority, deep);
}
else
{
return ISAM_ERROR;
}
}
else
{
ODBCTRACE ("\nWBEM ODBC Driver : fNeedChildren = FALSE\n");
}
return NO_ISAM_ERR;
}
/***************************************************************************/
// Checked for SetInterfaceSecurityEx on IWbemServices and IEnumWbemClassObject
SWORD INTFUNC ISAMBuildTreeChildren (HTREEITEM hParent,
char *namespaceName, //absolute name
CTreeCtrl& treeCtrl,
CConnectionDialog& dialog,
char *server,
// WBEM_LOGIN_AUTHENTICATION loginMethod,
char *username,
char *password,
BOOL fIntpretEmptPwdAsBlank,
char *locale,
char *authority,
BOOL deep)
{
ODBCTRACE ("\nWBEM ODBC Driver : ISAMBuildTreeChildren\n");
MyImpersonator fred (username, password, authority, "ISAMBuildTreeChildren");
//Advance to the namespace for which you require the children
DWORD dwAuthLevel = 0;
DWORD dwImpLevel = 0;
COAUTHIDENTITY* pAuthIdent = NULL;
IWbemServicesPtr pGateway = NULL;
ISAMGetGatewayServer (pGateway, (LPUSTR)server,
// loginMethod,
(LPUSTR)namespaceName, (LPUSTR)username, (LPUSTR)password, (LPUSTR)locale, (LPUSTR)authority,
dwAuthLevel, dwImpLevel, fIntpretEmptPwdAsBlank, &pAuthIdent);
if (pGateway == NULL)
{
ODBCTRACE ("\nWBEM ODBC Driver : ISAMBuildTreeChildren : Failed to get gateway server\n");
return ISAM_ERROR;
}
//cloaking
BOOL fIsLocalConnection = IsLocalServer(server);
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(pGateway, dwAuthLevel, dwImpLevel);
}
//Indicate that this node has been checked for children
TV_ITEM tvItem;
tvItem.hItem = hParent;
tvItem.mask = TVIF_PARAM;
if (treeCtrl.GetItem (&tvItem))
{
((ISAMTreeItemData*)tvItem.lParam)->fExpanded = TRUE;
}
//Get all children namespaces by fetching instances of __NAMESPACE
IEnumWbemClassObjectPtr pNamespaceEnum = NULL;
BSTR nspaceBSTR = SysAllocString(WBEMDR32_L_NAMESPACE);
IWbemContext* pContext = ISAMCreateLocaleIDContextObject(locale);
SCODE scCI = pGateway->CreateInstanceEnum(nspaceBSTR, 0, pContext, &pNamespaceEnum);
SysFreeString(nspaceBSTR);
if (pContext)
pContext->Release();
ISAMSetCloaking2(pNamespaceEnum,
fIsLocalConnection,
IsW2KOrMore(),
dwAuthLevel,
dwImpLevel,
pAuthIdent);
/*
if ( fIsLocalConnection && IsW2KOrMore() )
{
WbemSetDynamicCloaking(pNamespaceEnum, dwAuthLevel, dwImpLevel);
}
else
{
//Set Dcom blanket
SetInterfaceSecurityEx(pNamespaceEnum, pAuthIdent, gpPrincipal, dwAuthLevel, dwImpLevel);
}
*/
if ( FAILED(scCI) || (pNamespaceEnum == NULL) )
{
return ISAM_ERROR;
}
ULONG uRet = 0;
IWbemClassObjectPtr pNewInst = NULL;
pNamespaceEnum->Reset();
while ( S_OK == pNamespaceEnum->Next(-1, 1, &pNewInst, &uRet) )
{
//(14)
VARIANTARG var;
BSTR thenameBSTR = SysAllocString(WBEMDR32_L_NAME);
pNewInst->Get(thenameBSTR, 0, &var, NULL, NULL);
SysFreeString(thenameBSTR);
//RAID 42256
UINT cpThread = Utility_GetCodePageFromLCID(GetThreadLocale());
int len = WideCharToMultiByte(cpThread,WC_COMPOSITECHECK, (const wchar_t*)var.bstrVal, -1,
NULL, 0, NULL, NULL);
if (-1 != len)
{
char *name = new char [len + 1];
//RAID 42256
_bstr_t myValue((BSTR)var.bstrVal);
Utility_WideCharToDBCS(myValue, &name, len);
name [len] = '\0';
//Check if this child already exists in tree
CString fullPath = namespaceName;
fullPath += "\\";
fullPath += name;
HTREEITEM hDummy;
if (! dialog.FindAbsName((char*)(LPCTSTR)fullPath, hParent, hDummy) )
{
//Add child to tree control
HTREEITEM newTreeItem = NULL;
ISAMBuildTree (hParent, name,
treeCtrl,
dialog,
server,
// loginMethod,
username,
password,
fIntpretEmptPwdAsBlank,
locale,
authority,
deep,
deep,
newTreeItem);
if (deep && newTreeItem)
dialog.AddNamespaces(newTreeItem, FALSE);
}
delete name;
}
//Tidy Up
VariantClear(&var);
}
if (pAuthIdent )
{
WbemFreeAuthIdentity( pAuthIdent );
pAuthIdent = NULL;
}
return NO_ISAM_ERR;
}
/***************************************************************************/
// Checked for SetInterfaceSecurityEx on IWbemServices
void ISAMGetIWbemServices(LPISAM lpISAM, CSafeWbemServices& mServices, IWbemServicesPtr& myServicesPtr)
{
myServicesPtr = NULL;
mServices.GetInterfacePtr(myServicesPtr);
ISAMPatchUpGatewaySecurity(lpISAM, myServicesPtr);
}
void CSafeWbemServices::Transfer(CSafeWbemServices& original)
{
m_pStream = original.m_pStream;
original.m_pStream = NULL;
m_params = original.m_params;
original.m_params = NULL;
m_fValid = original.m_fValid;
original.m_fValid = FALSE;
}
HRESULT CSafeWbemServices::GetInterfacePtr(IWbemServicesPtr& pServices)
{
bool bRet = false;
if(m_pStream)
{
HRESULT hr;
//pop Com pointer out from stream
//as you are popping into &SmartPointer so increase in ref count
hr = CoGetInterfaceAndReleaseStream(m_pStream,IID_IWbemServices,(void**)&pServices);
m_pStream = NULL;
if (m_params)
m_params->m_myStream = NULL;
bRet = true;
if ( SUCCEEDED(hr) )
{
//push value back into stream
//as you are CoMarshalling into stream ref count bumped up by one
hr = CoMarshalInterThreadInterfaceInStream(IID_IWbemServices,pServices,&m_pStream);
if (m_params)
m_params->m_myStream = m_pStream;
}
}
return S_OK;
}
// Checked for SetInterfaceSecurityEx on IWbemServices
void CSafeWbemServices::SetInterfacePtr(LPISAM lpISAM, LPUSTR lpQualifierName, SWORD cbQualifierName)
{
ODBCTRACE("\nWBEM ODBC Driver :CSafeWbemServices::SetInterfacePtr\n");
//
//Create interface on Working Thread
//
//Create parameter set so that an equivalent one can be created
//on the working thread. (never used but must exist)
if (m_params)
{
BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_SERVICES, 0, (LPARAM)m_params);
m_pStream = NULL;
delete m_params;
m_params = NULL;
}
m_params = new MyWorkingThreadParams(lpISAM, lpQualifierName, cbQualifierName, m_pStream);
//post message to create this object on working thread
ODBCTRACE("\nWBEM ODBC Driver :CSafeWbemServices::SetInterfacePtr : pos 1\n");
BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_CREATE_SERVICES, 0, (LPARAM)m_params);
ODBCTRACE("\nWBEM ODBC Driver :CSafeWbemServices::SetInterfacePtr : pos 2\n");
m_fValid = ( SUCCEEDED(m_params->sc) ) ? TRUE : FALSE;
m_pStream = m_params->m_myStream;
}
CSafeWbemServices::CSafeWbemServices()
{
m_params = NULL;
m_fValid = FALSE;
m_pStream = NULL;
}
CSafeWbemServices::~CSafeWbemServices()
{
//clean up working thread parameters
//and IWbemServices object on working thread
if (m_params)
{
BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_SERVICES, 0, (LPARAM)m_params);
m_pStream = NULL;
delete m_params;
m_params = NULL;
}
}
void CSafeWbemServices::Invalidate()
{
if (m_params)
{
BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_SERVICES, 0, (LPARAM)m_params);
m_pStream = NULL;
delete m_params;
m_params = NULL;
}
m_fValid = FALSE;
m_pStream = NULL;
}
BOOL CSafeWbemServices::PostSuspensiveThreadMessage(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam)
{
BOOL status = FALSE;
ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage\n");
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage : in critical section\n");
//check data in lParam
MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
//Extract Event Handle
HANDLE EventHnd = myData->m_EventHnd;
//make sure the event is in its non-signaled state
//before posting the thread message
ResetEvent(EventHnd);
ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage: about to leave critical section\n");
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
//post message
ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage: PostThreadMessage\n");
status = PostThreadMessage(idThread, Msg, wParam, lParam);
if (!status)
{
ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage: PostThreadMessage failed\n");
}
//Make it suspensive
WaitForSingleObject(EventHnd, INFINITE);
ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage : After wait for single object\n");
return status;
}
// Checked for SetInterfaceSecurityEx on IWbemServices
LONG OnUserCreateServices(UINT wParam, LONG lParam)
{
ODBCTRACE("\n\n*****WBEM ODBC Driver : OnUserCreateServices*****\n\n");
COleInitializationManager oleManager;
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
ODBCTRACE("\nWBEM ODBC Driver : OnUserCreateServices : entered critial section\n");
//this is done on the worker thread
//check data in lParam
MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
//Tidy up existing stream
if(myData->m_myStream)
{
//pop interface into smart pointer.
//As it goes into &SmartPointer ref count stays the same
IWbemServicesPtr tempy;
HRESULT hr = CoGetInterfaceAndReleaseStream(myData->m_myStream, IID_IWbemServices, (void**)&tempy);
//when SmartPointer goes out of scope it will call Release and free up interface cleanly
}
myData->m_myStream = NULL;
//Setup impersonation on working thread
MyImpersonator im (myData->m_lpISAM, "Worker Thread:CreateServices");
//now add IWbemServices
IWbemServicesPtr tempy = NULL;
ISAMGetGatewayServer(tempy, myData->m_lpISAM, myData->m_lpQualifierName, myData->m_cbQualifierName);
myData->pGateway = tempy.Detach();
// CBString myServerStr;
// myServerStr.AddString( (LPSTR)myData->m_lpISAM->szServer, FALSE );
// CServerLocationCheck myCheck (myServerStr);
BOOL fIsLocalConnection = myData->m_lpISAM->fIsLocalConnection;//myCheck.IsLocal();
if ( fIsLocalConnection && (myData->m_lpISAM->fW2KOrMore) )
{
WbemSetDynamicCloaking(myData->pGateway, myData->m_lpISAM->dwAuthLevel, myData->m_lpISAM->dwImpLevel);
}
if (myData->pGateway)
{
HRESULT hr;
ODBCTRACE("\nWBEM ODBC Driver OnUserCreateServices : succeeded to create IWbemServices on working thread\n");
//push Com pointer in stream
//The CoMarshalling will bump up ref count by one
if (SUCCEEDED(hr =
CoMarshalInterThreadInterfaceInStream(IID_IWbemServices, myData->pGateway, &(myData->m_myStream))))
{
//
//Created services pointer now to be marshalled in stream
myData->sc = WBEM_S_NO_ERROR;
}
else
myData->sc = hr;
}
else
{
myData->sc = WBEM_E_FAILED;
ODBCTRACE("\nWBEM ODBC Driver OnUserCreateServices : failed to create IWbemServices on working thread\n");
}
//so that WaitForSingleObject returns
SetEvent(myData->m_EventHnd);
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
ODBCTRACE("\nWBEM ODBC Driver : OnUserCreateServices : left critial section\n");
return 0;
}
LONG OnUserRemoveServices(UINT wParam, LONG lParam)
{
ODBCTRACE("\n\n*****WBEM ODBC Driver : OnUserRemoveServices*****\n\n");
COleInitializationManager oleManager;
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveServices : entered crital section\n");
//this is done on the worker thread
//check data in lParam
MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveServices : about to Release IWbemServices\n");
//Remove the interface form the stream
if(myData->m_myStream)
{
//the release should pop any Com pointers out from stream
//the use of smart pointers should call Release to free up
// the Com pointer
IWbemServicesPtr tempy = NULL;
HRESULT hr = CoGetInterfaceAndReleaseStream(myData->m_myStream, IID_IWbemServices, (void**)&tempy);
myData->m_myStream = NULL;
}
if (myData->pGateway)
{
//remove the IWbemServices pointer from worker thread
myData->pGateway->Release();
myData->pGateway = NULL;
}
//so that WaitForSingleObject returns
SetEvent(myData->m_EventHnd);
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveServices : left critial section\n");
return 0;
}
LONG OnUserCreateEnum(UINT wParam, LONG lParam)
{
ODBCTRACE("\n\n*****WBEM ODBC Driver : OnUserCreateEnum*****\n\n");
COleInitializationManager oleManager;
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
ODBCTRACE("\nWBEM ODBC Driver : OnUserCreateEnum : entered critial section\n");
//this is done on the worker thread
//check data in lParam
MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
//now add IEnumWbemClassObject
//first check if you need to ExecQuery or CreateInstanceEnum
//remember to return scode in myData
if(myData->m_myStream)
{
//the release should pop any Com pointers out from stream
//the use of smart pointers should call Release to free up
// the Com pointer
IEnumWbemClassObjectPtr tempy = NULL;
HRESULT hr = CoGetInterfaceAndReleaseStream(myData->m_myStream, IID_IEnumWbemClassObject, (void**)&tempy);
}
myData->m_myStream = NULL;
//Create tempory context object
IWbemContext* pContext = ISAMCreateLocaleIDContextObject(myData->m_lpISAM->m_Locale);
//Setup impersonation on working thread
MyImpersonator im (myData->m_lpISAM, "Worker Thread");
IWbemServicesPtr myServicesPtr = NULL;
ISAMGetIWbemServices(myData->m_lpISAM, *(myData->pServ), myServicesPtr);
// CBString myServerStr;
// myServerStr.AddString( (LPSTR)myData->m_lpISAM->szServer, FALSE );
// CServerLocationCheck myCheck (myServerStr);
BOOL fIsLocalConnection = myData->m_lpISAM->fIsLocalConnection;//myCheck.IsLocal();
if ( fIsLocalConnection && (myData->m_lpISAM->fW2KOrMore) )
{
WbemSetDynamicCloaking(myServicesPtr, myData->m_lpISAM->dwAuthLevel, myData->m_lpISAM->dwImpLevel);
}
DWORD dwSize;
char buffer[1001];
buffer[0] = 0;
GetUserName(buffer, &dwSize);
CString lpMessage;
lpMessage.Format("\nUser Account just before Enum or ExecQuery : %s\n", buffer);
ODBCTRACE(lpMessage);
if ( (myData->fIsExecQuery) == WMI_CREATE_INST_ENUM )
{
//CreateInstanceEnum
myData->sc = myServicesPtr->CreateInstanceEnum(myData->tableName, 0, pContext, &(myData->pEnum));
}
else
{
//ExecQuery
long flags = 0;
if ( (myData->fIsExecQuery) == WMI_EXEC_FWD_ONLY )
flags = WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY;
else
if ( (myData->fIsExecQuery) == WMI_PROTOTYPE )
flags = WBEM_FLAG_PROTOTYPE;
BSTR wqlBSTR = SysAllocString(WBEMDR32_L_WQL);
myData->sc = myServicesPtr->ExecQuery(wqlBSTR, myData->sqltextBSTR, flags, pContext, &(myData->pEnum));
SysFreeString(wqlBSTR);
}
//Tidy up
if (pContext)
pContext->Release();
if ( SUCCEEDED(myData->sc) )
{
ODBCTRACE("\nWBEM ODBC Driver OnUserCreateEnum : succeeded to create IEnumWbemClassObject on working thread\n");
if (myData->pEnum)
{
//push Com pointer in stream
//The CoMarshalling will bump the ref count up by one
if (FAILED(
CoMarshalInterThreadInterfaceInStream(IID_IEnumWbemClassObject, myData->pEnum, &(myData->m_myStream))))
{
ODBCTRACE("\nWBEM ODBC Driver OnUserCreateEnum : failed to CoMarshalInterThreadInterfaceInStream\n");
}
}
}
else
{
ODBCTRACE("\nWBEM ODBC Driver OnUserCreateEnum : failed to create IEnumWbemClassObject on working thread\n");
}
//so that WaitForSingleObject returns
SetEvent(myData->m_EventHnd);
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
ODBCTRACE("\nWBEM ODBC Driver : OnUserCreateEnum : left critial section\n");
return 0;
}
LONG OnUserRemoveEnum(UINT wParam, LONG lParam)
{
ODBCTRACE("\n\n*****WBEM ODBC Driver : OnUserRemoveEnum*****\n\n");
COleInitializationManager oleManager;
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveEnum : entered crital section\n");
//this is done on the worker thread
//check data in lParam
MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveEnum : about to Release IEnumWbemClassObject\n");
if(myData->m_myStream)
{
//the release should pop any Com pointers out from stream
//the use of smart pointers should call Release to free up
// the Com pointer
IEnumWbemClassObjectPtr tempy = NULL;
HRESULT hr = CoGetInterfaceAndReleaseStream(myData->m_myStream, IID_IEnumWbemClassObject, (void**)&tempy);
}
myData->m_myStream = NULL;
if (myData->pEnum)
{
//remove the IWbemServices pointer from worker thread
myData->pEnum->Release();
myData->pEnum = NULL;
}
//so that WaitForSingleObject returns
SetEvent(myData->m_EventHnd);
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
ODBCTRACE("\nWBEM ODBC Driver : OnUserRemoveEnum : left critial section\n");
return 0;
}
void OnIncreamentRefCount(UINT wParam, LONG lParam)
{
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
++glob_myWorkerThread.m_cRef;
CString message;
message.Format ("\n***** Working thread count (increment) = %ld *****\n", glob_myWorkerThread.m_cRef);
ODBCTRACE(message);
//check data in lParam
MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
//so that WaitForSingleObject returns
SetEvent(myData->m_EventHnd);
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
}
void OnDecreamentRefCount(UINT wParam, LONG lParam)
{
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
if (glob_myWorkerThread.m_cRef)
{
--glob_myWorkerThread.m_cRef;
CString message;
message.Format ("\n***** Working thread count (descrement) = %ld *****\n", glob_myWorkerThread.m_cRef);
ODBCTRACE(message);
}
//check data in lParam
MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
//so that WaitForSingleObject returns
SetEvent(myData->m_EventHnd);
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
}
//DWORD WINAPI MyWorkerThread(LPVOID myVal)
unsigned __stdcall MyWorkerThread(LPVOID myVal)
{
//this is done on the worker thread
DWORD dwThreadId = GetCurrentThreadId();
//force a thread message queue to be created
MSG msg;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
//so that WaitForSingleObject returns
//infinate loop for thread to read messages
BOOL status = FALSE;
BOOL myLoop = TRUE;
while (myLoop)
{
//look for messages in the range WM_USER, MYUSRMESS_REMOVE_ENUM
status = PeekMessage(&msg, NULL, WM_USER, MYUSRMESS_REMOVE_ENUM, PM_NOREMOVE);
if (status)
{
switch (msg.message)
{
case MYUSRMESS_CREATE_SERVICES:
{
ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_CREATE_SERVICES\n");
PeekMessage(&msg, NULL, MYUSRMESS_CREATE_SERVICES, MYUSRMESS_CREATE_SERVICES, PM_REMOVE);
OnUserCreateServices(msg.wParam, msg.lParam);
}
break;
case MYUSRMESS_REMOVE_SERVICES:
{
ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_REMOVE_SERVICES\n");
PeekMessage(&msg, NULL, MYUSRMESS_REMOVE_SERVICES, MYUSRMESS_REMOVE_SERVICES, PM_REMOVE);
OnUserRemoveServices(msg.wParam, msg.lParam);
}
break;
case MYUSRMESS_CLOSE_WKERTHRED:
{
ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_CLOSE_WKERTHRED\n");
PeekMessage(&msg, NULL, MYUSRMESS_CLOSE_WKERTHRED, MYUSRMESS_CLOSE_WKERTHRED, PM_REMOVE);
ISAMCloseWorkerThread2(msg.wParam, msg.lParam);
myLoop = FALSE; //need to exit thread when ISAMCloseWorkerThread2 exists
}
break;
case MYUSRMESS_REFCOUNT_INCR:
{
ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_REFCOUNT_INCR\n");
PeekMessage(&msg, NULL, MYUSRMESS_REFCOUNT_INCR, MYUSRMESS_REFCOUNT_INCR, PM_REMOVE);
OnIncreamentRefCount(msg.wParam, msg.lParam);
}
break;
case MYUSRMESS_REFCOUNT_DECR:
{
ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_REFCOUNT_DECR\n");
PeekMessage(&msg, NULL, MYUSRMESS_REFCOUNT_DECR, MYUSRMESS_REFCOUNT_DECR, PM_REMOVE);
OnDecreamentRefCount(msg.wParam, msg.lParam);
}
break;
case MYUSRMESS_CREATE_ENUM:
{
ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_CREATE_ENUM\n");
PeekMessage(&msg, NULL, MYUSRMESS_CREATE_ENUM, MYUSRMESS_CREATE_ENUM, PM_REMOVE);
OnUserCreateEnum(msg.wParam, msg.lParam);
}
break;
case MYUSRMESS_REMOVE_ENUM:
{
ODBCTRACE("\nWBEM ODBC Driver : MyWorkerThread : MYUSRMESS_REMOVE_ENUM\n");
PeekMessage(&msg, NULL, MYUSRMESS_REMOVE_ENUM, MYUSRMESS_REMOVE_ENUM, PM_REMOVE);
OnUserRemoveEnum(msg.wParam, msg.lParam);
}
break;
default:
{
CString myMessage;
myMessage.Format("\nWBEM ODBC Driver : MyWorkerThread : unknown message %ld which I will remove off the thread queue\n", msg.message);
ODBCTRACE(myMessage);
PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
}
break;
}
}
Sleep(10);
}
//The thread will exit here
return 500;
}
CWorkerThreadManager::CWorkerThreadManager()
{
fIsValid = FALSE;
//initalize critical section for shared data
InitializeCriticalSection(&m_cs);
dwThreadId = 0;
m_cRef = 0;
hr = NULL;
}
void CWorkerThreadManager::CreateWorkerThread()
{
//Create a worker thread
EnterCriticalSection(& m_cs );
dwThreadId = 0;
m_cRef = 1; //sets the ref count to 1
hr = (HANDLE)_beginthreadex(NULL, 0, &MyWorkerThread, NULL, 0, (unsigned int*)&dwThreadId);
fIsValid = TRUE;
LeaveCriticalSection(& m_cs );
}
void CWorkerThreadManager::Invalidate()
{
//only called after working thread is exited
dwThreadId = 0;
hr = NULL;
fIsValid = FALSE;
m_cRef = 0;
}
void ISAMCloseWorkerThread1()
{
ODBCTRACE("\n\n***** ISAMCloseWorkerThread1 *****\n\n");
MyWorkingThreadParams* m_params = new MyWorkingThreadParams(NULL, NULL, 0, NULL);
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
HANDLE EventHnd = m_params->m_EventHnd;
ResetEvent(EventHnd);
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
PostThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_CLOSE_WKERTHRED, 0, (LPARAM)m_params);
//Wait on termination of thread
WaitForSingleObject(glob_myWorkerThread.GetThreadHandle(), INFINITE);
delete m_params;
}
CWorkerThreadManager::~CWorkerThreadManager()
{
//close thread
ODBCTRACE("\n\n***** Shutting down worker thread *****\n\n");
//close critical section
DeleteCriticalSection(&m_cs);
}
void ISAMCloseWorkerThread2(UINT wParam, LONG lParam)
{
//this is done on the worker thread
ODBCTRACE("\n\n***** ISAMCloseWorkerThread2 *****\n\n");
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
//this is done on the worker thread
//check data in lParam
MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
//so that WaitForSingleObject returns
//so ISAMCloseWorkerThread1 can continue and Invalidate the
//global worker thread
SetEvent(myData->m_EventHnd);
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
//when you exit this method and return to 'MyWorkerThread'
//it will exit the loop and thus automatically terminate the thread
}
MyWorkingThreadParams::MyWorkingThreadParams(LPISAM lpISAM, LPUSTR lpQualifierName, SWORD cbQualifierName, IStream* myStream)
{
//This will be created on worker thread
m_lpISAM = lpISAM;
m_lpQualifierName = lpQualifierName;
m_cbQualifierName = cbQualifierName;
m_myStream = myStream;
pGateway = NULL; //will be filled in later
pEnum = NULL;
//Create an event object
//so that message to worker thread can be suspensive
m_EventHnd = CreateEvent(NULL, TRUE, FALSE, NULL);
}
MyWorkingThreadParams::MyWorkingThreadParams(LPISAM lpISAM, WmiEnumTypes a_fIsExecQuery, BSTR theBstrValue, CSafeWbemServices* a_pServ, IStream* myStream)
{
//This will be created on worker thread
m_lpISAM = lpISAM;
fIsExecQuery = a_fIsExecQuery;
sqltextBSTR = NULL;
tableName = NULL;
if (a_fIsExecQuery != WMI_CREATE_INST_ENUM)
{
sqltextBSTR = theBstrValue;
}
else
{
tableName = theBstrValue;
}
pServ = a_pServ;
m_myStream = myStream;
pGateway = NULL;
pEnum = NULL; //will be filled in later
sc = 0;
//Create an event object
//so that message to worker thread can be suspensive
m_EventHnd = CreateEvent(NULL, TRUE, FALSE, NULL);
}
MyWorkingThreadParams::~MyWorkingThreadParams()
{
//This will be cleaned up on worker thread
if (m_EventHnd)
{
CloseHandle(m_EventHnd);
}
if (pGateway)
{
ODBCTRACE("\nShould never get here, deleting Gateway\n");
}
if (pEnum)
{
ODBCTRACE("\nShould never get here, deleting Enumeration\n");
}
}
COleInitializationManager::COleInitializationManager()
{
//Initialize Ole
OleInitialize(0);
}
COleInitializationManager::~COleInitializationManager()
{
//Uninitialize OLE
OleUninitialize();
}
CSafeIEnumWbemClassObject::CSafeIEnumWbemClassObject()
{
m_fValid = FALSE;
m_pStream = NULL;
m_params = NULL;
}
CSafeIEnumWbemClassObject::~CSafeIEnumWbemClassObject()
{
if (m_params)
{
BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_ENUM, 0, (LPARAM)m_params);
m_pStream = NULL;
delete m_params;
m_params = NULL;
}
}
BOOL CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam)
{
BOOL status = FALSE;
ODBCTRACE("\nWBEM ODBC Driver : CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage\n");
EnterCriticalSection(& (glob_myWorkerThread.m_cs) );
ODBCTRACE("\nWBEM ODBC Driver : CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage : in critical section\n");
//check data in lParam
MyWorkingThreadParams* myData = (MyWorkingThreadParams*)lParam;
//Extract Event Handle
HANDLE EventHnd = myData->m_EventHnd;
//make sure the event is in its non-signaled state
//before posting the thread message
ResetEvent(EventHnd);
ODBCTRACE("\nWBEM ODBC Driver : CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage: about to leave critical section\n");
LeaveCriticalSection(& (glob_myWorkerThread.m_cs) );
//post message
ODBCTRACE("\nWBEM ODBC Driver : CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage: PostThreadMessage\n");
status = PostThreadMessage(idThread, Msg, wParam, lParam);
if (!status)
{
ODBCTRACE("\nWBEM ODBC Driver : CSafeWbemServices::PostSuspensiveThreadMessage: PostThreadMessage failed\n");
}
//Make it suspensive
WaitForSingleObject(EventHnd, INFINITE);
ODBCTRACE("\nWBEM ODBC Driver : CSafeIEnumWbemClassObject::PostSuspensiveThreadMessage : After wait for single object\n");
return status;
}
HRESULT CSafeIEnumWbemClassObject::GetInterfacePtr(IEnumWbemClassObjectPtr& pIEnum)
{
bool bRet = false;
if(m_pStream)
{
HRESULT hr;
//pop Com pointer out from stream
//as we are using &SmartPointer the ref count stays the same
hr = CoGetInterfaceAndReleaseStream(m_pStream,IID_IEnumWbemClassObject,(void**)&pIEnum);
m_pStream = NULL;
if (m_params)
m_params->m_myStream = NULL;
bRet = true;
if ( SUCCEEDED(hr) )
{
//push the interface back into stream.
//As we are CoMarshalling the interface the ref count bumps up by one
hr = CoMarshalInterThreadInterfaceInStream(IID_IEnumWbemClassObject,pIEnum,&m_pStream);
if (m_params)
m_params->m_myStream = m_pStream;
}
}
return S_OK;
}
HRESULT CSafeIEnumWbemClassObject::SetInterfacePtr(LPISAM lpISAM, WmiEnumTypes fIsEXecQuery, BSTR theBstrValue, CSafeWbemServices* pServ)
{
//Tidy up any previous values
if (m_params)
{
BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_ENUM, 0, (LPARAM)m_params);
m_pStream = NULL;
delete m_params;
m_params = NULL;
}
//Set new value
m_params = new MyWorkingThreadParams(lpISAM, fIsEXecQuery, theBstrValue, pServ, m_pStream);
//post message to create this object on working thread
ODBCTRACE("\nWBEM ODBC Driver :CSafeWbemServices::SetInterfacePtr : pos 1\n");
BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_CREATE_ENUM, 0, (LPARAM)m_params);
ODBCTRACE("\nWBEM ODBC Driver :CSafeWbemServices::SetInterfacePtr : pos 2\n");
m_fValid = ( SUCCEEDED(m_params->sc) ) ? TRUE : FALSE;
m_pStream = m_params->m_myStream;
return (m_params->sc);
}
void CSafeIEnumWbemClassObject::Invalidate()
{
if (m_params)
{
BOOL status = PostSuspensiveThreadMessage(glob_myWorkerThread.GetThreadId(), MYUSRMESS_REMOVE_ENUM, 0, (LPARAM)m_params);
m_pStream = NULL;
delete m_params;
m_params = NULL;
}
m_pStream = NULL;
m_fValid = FALSE;
}
// Checked for SetInterfaceSecurityEx on IWbemServices
BOOL IsLocalServer(LPSTR szServer)
{
//A local server could be specified as a NULL or blank string
//a '.' character or a fully qualified \\MyLocalServer
//we need to check each of these cases
if (!szServer || !*szServer)
return TRUE;
// Get past the \\ if any.
if (szServer[0] == '\\' && szServer[1] == '\\')
szServer += 2;
// Check for '.'.
if (!strcmp(szServer, "."))
return TRUE;
// Get the server name and compare.
char szName[MAX_COMPUTERNAME_LENGTH + 1] = "";
DWORD dwSize = sizeof(szName);
GetComputerNameA(szName, &dwSize);
return _stricmp(szServer, szName) == 0;
}