|
|
/***************************************************************************/ /* 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; }
|