12720 lines
452 KiB
C++
12720 lines
452 KiB
C++
//***************************************************************************
|
|
//
|
|
// (c) 1999-2001 by Microsoft Corp. All Rights Reserved.
|
|
//
|
|
// ESEUTILS.cpp
|
|
//
|
|
// cvadai 6-May-1999 created.
|
|
//
|
|
//***************************************************************************
|
|
// #define OBJECT_BLOB_CRC
|
|
|
|
#define _JET_PROCS_CPP_
|
|
#pragma warning( disable : 4786 ) // identifier was truncated to 'number' characters in the
|
|
#pragma warning( disable : 4251 ) // needs to have dll-interface to be used by clients of class
|
|
|
|
#include "precomp.h"
|
|
#include <std.h>
|
|
#include <cominit.h>
|
|
#include <ese.h>
|
|
#include <sqlexec.h>
|
|
#include <sqlcache.h>
|
|
#include <eseobjs.h>
|
|
#include <repdrvr.h>
|
|
#include <wbemint.h>
|
|
#include <math.h>
|
|
#include <objbase.h>
|
|
#include <resource.h>
|
|
#include <reputils.h>
|
|
#include <arena.h>
|
|
#include <crc64.h>
|
|
#include <smrtptr.h>
|
|
#include <eseitrtr.h>
|
|
#include <wqltoese.h>
|
|
#include <eseutils.h>
|
|
#include <repcache.h>
|
|
#include <objbase.h>
|
|
#include <wbemprov.h>
|
|
|
|
#define MAX_STRING_WIDTH 255
|
|
|
|
#define OBJECTMAP_COL_OBJECTID 1
|
|
#define OBJECTMAP_COL_OBJECTPATH 2
|
|
#define OBJECTMAP_COL_OBJECTKEY 3
|
|
#define OBJECTMAP_COL_REFERENCECOUNT 4
|
|
#define OBJECTMAP_COL_OBJECTSTATE 5
|
|
#define OBJECTMAP_COL_CLASSID 6
|
|
#define OBJECTMAP_COL_OBJECTFLAGS 7
|
|
#define OBJECTMAP_COL_OBJECTSCOPEID 8
|
|
|
|
#define CLASSMAP_COL_CLASSID 1
|
|
#define CLASSMAP_COL_CLASSNAME 2
|
|
#define CLASSMAP_COL_SUPERCLASSID 3
|
|
#define CLASSMAP_COL_DYNASTYID 4
|
|
#define CLASSMAP_COL_CLASSBUFFER 5
|
|
|
|
#define PROPERTYMAP_COL_CLASSID 1
|
|
#define PROPERTYMAP_COL_PROPERTYID 2
|
|
#define PROPERTYMAP_COL_STORAGETYPEID 3
|
|
#define PROPERTYMAP_COL_CIMTYPEID 4
|
|
#define PROPERTYMAP_COL_PROPERTYNAME 5
|
|
#define PROPERTYMAP_COL_FLAGS 6
|
|
#define PROPERTYMAP_COL_REFCLASSID 7
|
|
|
|
#define CLASSKEYS_COL_CLASSID 1
|
|
#define CLASSKEYS_COL_PROPERTYID 2
|
|
|
|
#define REFPROPS_COL_CLASSID 1
|
|
#define REFPROPS_COL_PROPERTYID 2
|
|
#define REFPROPS_COL_REFCLASSID 3
|
|
|
|
#define CLASSDATA_COL_OBJECTID 1
|
|
#define CLASSDATA_COL_PROPERTYID 2
|
|
#define CLASSDATA_COL_ARRAYPOS 3
|
|
#define CLASSDATA_COL_QFRPOS 4
|
|
#define CLASSDATA_COL_CLASSID 5
|
|
#define CLASSDATA_COL_STRINGVALUE 6
|
|
#define CLASSDATA_COL_NUMERICVALUE 7
|
|
#define CLASSDATA_COL_REFID 8
|
|
#define CLASSDATA_COL_REALVALUE 9
|
|
#define CLASSDATA_COL_REFCLASSID 10
|
|
#define CLASSDATA_COL_FLAGS 11
|
|
|
|
#define CLASSIMAGES_COL_OBJECTID 1
|
|
#define CLASSIMAGES_COL_PROPERTYID 2
|
|
#define CLASSIMAGES_COL_ARRAYPOS 3
|
|
#define CLASSIMAGES_COL_IMAGEVALUE 4
|
|
|
|
#define INDEXTBL_COL_OBJECTID 1
|
|
#define INDEXTBL_COL_PROPERTYID 2
|
|
#define INDEXTBL_COL_ARRAYPOS 3
|
|
#define INDEXTBL_COL_INDEXVALUE 4
|
|
|
|
#define CONTAINEROBJS_COL_CONTAINERID 1
|
|
#define CONTAINEROBJS_COL_CONTAINEEID 2
|
|
|
|
#define AUTODELETE_COL_OBJECTID 1
|
|
|
|
#define SCOPEMAP_COL_OBJECTID 1
|
|
#define SCOPEMAP_COL_SCOPEPATH 2
|
|
#define SCOPEMAP_COL_PARENTID 3
|
|
|
|
typedef std::vector <SQL_ID> SQLIDs;
|
|
typedef std::vector <DWORD> IDs;
|
|
typedef std::vector <_bstr_t> _bstr_ts;
|
|
typedef std::map <DWORD, DWORD> Properties;
|
|
JET_INSTANCE gJetInst = NULL;
|
|
typedef std::map <DWORD, SQLIDs> SessionDynasties;
|
|
|
|
|
|
LPWSTR StripQuotes2(LPWSTR lpText)
|
|
{
|
|
wchar_t *pszTemp = new wchar_t [wcslen(lpText)+1];
|
|
if (pszTemp)
|
|
{
|
|
int iPos = 0;
|
|
BOOL bOnQuote = FALSE;
|
|
int iLen = wcslen(lpText);
|
|
if (iLen)
|
|
{
|
|
for (int i = 0; i < iLen; i++)
|
|
{
|
|
WCHAR t = lpText[i];
|
|
if (t == '\'')
|
|
{
|
|
if (!bOnQuote)
|
|
{
|
|
if (lpText[i+1] == '\'')
|
|
{
|
|
bOnQuote = TRUE;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
bOnQuote = FALSE;
|
|
pszTemp[iPos] = t;
|
|
iPos++;
|
|
}
|
|
}
|
|
pszTemp[iPos] = '\0';
|
|
}
|
|
return pszTemp;
|
|
}
|
|
|
|
void FreeBstr(BSTR * ppStr)
|
|
{
|
|
if (ppStr)
|
|
{
|
|
SysFreeString(*ppStr);
|
|
*ppStr = NULL;
|
|
}
|
|
}
|
|
|
|
HRESULT LoadSchemaProperties (CSQLConnection *pConn, CSchemaCache *pCache, SQL_ID dClassId)
|
|
{
|
|
// Enumerate properties
|
|
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
PROPERTYMAP pm;
|
|
hr = GetFirst_PropertyMapByClass(pConn, dClassId, pm);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
hr = pCache->AddPropertyInfo (pm.iPropertyId,
|
|
pm.sPropertyName, pm.dClassId, pm.iStorageTypeId, pm.iCIMTypeId, pm.iFlags,
|
|
0, L"", 0, 0);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
pm.Clear();
|
|
break;
|
|
}
|
|
|
|
hr = GetNext_PropertyMap(pConn, pm);
|
|
}
|
|
|
|
CLASSKEYS ck;
|
|
hr = GetFirst_ClassKeys (pConn, dClassId, ck);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
pCache->SetIsKey(ck.dClassId, ck.iPropertyId);
|
|
|
|
hr = GetNext_ClassKeys(pConn, ck);
|
|
}
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbController::GetLogonTemplate
|
|
//
|
|
//***************************************************************************
|
|
HRESULT STDMETHODCALLTYPE CWmiDbController::GetLogonTemplate(
|
|
/* [in] */ LCID lLocale,
|
|
/* [in] */ DWORD dwFlags,
|
|
/* [out] */ WMIDB_LOGON_TEMPLATE __RPC_FAR *__RPC_FAR *ppTemplate)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
if (dwFlags != 0 || !ppTemplate)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
try
|
|
{
|
|
if (ppTemplate)
|
|
{
|
|
WMIDB_LOGON_TEMPLATE *pTemp = new WMIDB_LOGON_TEMPLATE;
|
|
|
|
if (pTemp)
|
|
{
|
|
pTemp->dwArraySize = 5;
|
|
HINSTANCE hRCDll = GetResourceDll(lLocale);
|
|
if (!hRCDll)
|
|
{
|
|
LCID lTemp = GetUserDefaultLangID();
|
|
hRCDll = GetResourceDll(lTemp);
|
|
if (!hRCDll)
|
|
{
|
|
lTemp = GetSystemDefaultLangID();
|
|
hRCDll = GetResourceDll(lTemp);
|
|
if (!hRCDll)
|
|
hRCDll = LoadLibrary(L"reprc.dll"); // Last resort - try the current directory.
|
|
}
|
|
}
|
|
|
|
wchar_t wDB[101], wUser[101], wPwd[101], wLocale[101], wMode[101];
|
|
pTemp->pParm = new WMIDB_LOGON_PARAMETER[6];
|
|
if (pTemp->pParm)
|
|
{
|
|
|
|
if (hRCDll)
|
|
{
|
|
LoadString(hRCDll, IDS_WMI_USER_NAME, wUser, 100);
|
|
LoadString(hRCDll, IDS_WMI_PASSWORD, wPwd, 100);
|
|
LoadString(hRCDll, IDS_WMI_DATABASE, wDB, 100);
|
|
LoadString(hRCDll, IDS_WMI_LOCALE, wLocale, 100);
|
|
LoadString(hRCDll, IDS_WMI_READMODE, wMode, 100);
|
|
FreeLibrary(hRCDll);
|
|
}
|
|
else
|
|
{
|
|
wcscpy(wDB, L"Database");
|
|
wcscpy(wUser, L"UserID");
|
|
wcscpy(wPwd, L"Password");
|
|
wcscpy(wLocale, L"Locale");
|
|
wcscpy(wMode, L"Access Mode");
|
|
}
|
|
|
|
pTemp->pParm[0].dwId = DBPROP_INIT_MODE;
|
|
pTemp->pParm[0].strParmDisplayName = SysAllocString(wMode);
|
|
VariantInit(&(pTemp->pParm[0].Value));
|
|
pTemp->pParm[0].Value.vt = VT_I4;
|
|
pTemp->pParm[0].Value.lVal = DB_MODE_READWRITE ;
|
|
|
|
pTemp->pParm[1].dwId = DBPROP_AUTH_USERID;
|
|
pTemp->pParm[1].strParmDisplayName = SysAllocString(wUser);
|
|
VariantInit(&(pTemp->pParm[1].Value));
|
|
|
|
pTemp->pParm[2].dwId = DBPROP_AUTH_PASSWORD;
|
|
pTemp->pParm[2].strParmDisplayName = SysAllocString(wPwd);
|
|
VariantInit(&(pTemp->pParm[2].Value));
|
|
|
|
pTemp->pParm[3].dwId = DBPROP_INIT_DATASOURCE;
|
|
pTemp->pParm[3].strParmDisplayName = SysAllocString(wDB);
|
|
VariantInit(&(pTemp->pParm[3].Value));
|
|
|
|
pTemp->pParm[4].dwId = DBPROP_INIT_LCID;
|
|
pTemp->pParm[4].strParmDisplayName = SysAllocString(wLocale);
|
|
VariantInit(&(pTemp->pParm[4].Value));
|
|
pTemp->pParm[4].Value.lVal = lLocale;
|
|
pTemp->pParm[4].Value.vt = VT_I4;
|
|
|
|
*ppTemplate = pTemp;
|
|
}
|
|
else
|
|
{
|
|
delete pTemp;
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
catch (...)
|
|
{
|
|
ERRORTRACE((LOG_WBEMCORE, "Fatal error in CWmiDbController::GetLogonTemplate\n"));
|
|
hr = WBEM_E_CRITICAL_ERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetPath
|
|
//
|
|
//***************************************************************************
|
|
|
|
LPWSTR GetPath (LPCWSTR lpDatabaseName)
|
|
{
|
|
wchar_t *pPath = NULL;
|
|
if (lpDatabaseName && wcslen(lpDatabaseName))
|
|
{
|
|
pPath = new wchar_t [(wcslen(lpDatabaseName))+1];
|
|
if (pPath)
|
|
{
|
|
BOOL bDone = FALSE;
|
|
wchar_t *Temp = new wchar_t [wcslen(lpDatabaseName)+1];
|
|
if (Temp)
|
|
{
|
|
CDeleteMe <wchar_t> d2 (Temp);
|
|
wcscpy(Temp, lpDatabaseName);
|
|
|
|
wchar_t *pTemp = wcsstr(Temp, L"\\");
|
|
|
|
while (!bDone)
|
|
{
|
|
pTemp++;
|
|
wchar_t *pTemp2 = wcsstr(pTemp, L"\\");
|
|
if (!pTemp2)
|
|
{
|
|
bDone = TRUE;
|
|
int iLen = (pTemp - Temp);
|
|
wcsncpy(pPath, Temp, iLen);
|
|
pPath[iLen] = L'\0';
|
|
break;
|
|
}
|
|
else
|
|
pTemp = pTemp2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return pPath;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteDatabase
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteDatabase(LPCWSTR lpDatabaseName)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Enumerate all files in the directory
|
|
// and delete them all
|
|
// Also check if there are any conflictingly-named
|
|
// subdirectories.
|
|
|
|
ERRORTRACE((LOG_WBEMCORE, "Database %sis out-of-date. Deleting...\n", lpDatabaseName));
|
|
|
|
if (!DeleteFile(lpDatabaseName))
|
|
{
|
|
DWORD err = GetLastError();
|
|
RemoveDirectory(lpDatabaseName);
|
|
}
|
|
|
|
LPWSTR lpPath = GetPath(lpDatabaseName);
|
|
if (lpPath)
|
|
{
|
|
wchar_t *pTemp = new wchar_t [wcslen(lpDatabaseName) + 50];
|
|
CDeleteMe <wchar_t> d2 (pTemp);
|
|
if (pTemp)
|
|
{
|
|
swprintf(pTemp, L"%sedb.log", lpPath);
|
|
if (!DeleteFile(pTemp))
|
|
RemoveDirectory(pTemp);
|
|
|
|
swprintf(pTemp, L"%sedb.chk", lpPath);
|
|
if (!DeleteFile(pTemp))
|
|
RemoveDirectory(pTemp);
|
|
|
|
swprintf(pTemp, L"%sres1.log", lpPath);
|
|
if (!DeleteFile(pTemp))
|
|
RemoveDirectory(pTemp);
|
|
|
|
swprintf(pTemp, L"%sres2.log", lpPath);
|
|
if (!DeleteFile(pTemp))
|
|
RemoveDirectory(pTemp);
|
|
|
|
swprintf(pTemp, L"%stmp.edb", lpPath);
|
|
if (!DeleteFile(pTemp))
|
|
RemoveDirectory(pTemp);
|
|
|
|
swprintf(pTemp, L"%s*.log", lpPath);
|
|
|
|
_bstr_ts names;
|
|
WIN32_FIND_DATA fd;
|
|
HANDLE hFile = FindFirstFile(pTemp, &fd);
|
|
while (TRUE)
|
|
{
|
|
if (wcscmp(fd.cFileName, L".") &&
|
|
wcscmp(fd.cFileName, L".."))
|
|
{
|
|
swprintf(pTemp, L"%s%s", lpPath, fd.cFileName);
|
|
names.push_back(pTemp);
|
|
}
|
|
|
|
if (!FindNextFile(hFile, &fd))
|
|
break;
|
|
}
|
|
|
|
for (int i = 0; i < names.size(); i++)
|
|
{
|
|
if (!DeleteFile(names.at(i)))
|
|
RemoveDirectory(names.at(i));
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
hr = WBEM_E_FAILED;
|
|
|
|
return hr;
|
|
}
|
|
|
|
BOOL CheckVersion (JET_SESID sesid, JET_DBID dbid, int iVersion)
|
|
{
|
|
BOOL bDelete = FALSE;
|
|
JET_ERR err;
|
|
JET_TABLEID tableid;
|
|
JET_COLUMNID id;
|
|
DWORD dwCurrVer = 0;
|
|
|
|
err = JetOpenTable (sesid, dbid, "DBVersion", NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
JET_COLUMNDEF columnDef;
|
|
err = JetGetColumnInfo(sesid, dbid, "DBVersion", "Version",
|
|
&columnDef, sizeof(JET_COLUMNDEF), 0);
|
|
|
|
if (err < JET_errSuccess)
|
|
{
|
|
columnDef.cp = 1200; // Unicode? Otherwise, its 1252.
|
|
columnDef.wCountry = 1;
|
|
columnDef.langid = 1033;
|
|
columnDef.wCollate = 0;
|
|
columnDef.cbStruct = sizeof(JET_COLUMNDEF);
|
|
|
|
columnDef.columnid = 1;
|
|
columnDef.coltyp = JET_coltypLong;
|
|
columnDef.grbit = 0 ;
|
|
columnDef.cbMax = 0;
|
|
err = JetAddColumn(sesid, tableid, "Version", &columnDef, "", 0, &id);
|
|
}
|
|
else
|
|
id = columnDef.columnid;
|
|
|
|
ULONG lLen;
|
|
err = JetMove(sesid, tableid, JET_MoveFirst, 0);
|
|
err = JetRetrieveColumn(sesid, tableid, id,
|
|
&dwCurrVer, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess == err && lLen != 0)
|
|
{
|
|
if (iVersion != dwCurrVer)
|
|
bDelete = TRUE;
|
|
}
|
|
JetCloseTable(sesid, tableid);
|
|
}
|
|
else
|
|
{
|
|
// Do any other tables exist?
|
|
err = JetOpenTable(sesid, dbid, "ClassMap", NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
bDelete = TRUE;
|
|
JetCloseTable(sesid, tableid);
|
|
}
|
|
}
|
|
|
|
return bDelete;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// AttachESEDatabase
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT AttachESEDatabase(DBPROPSET *pTemplate, CSQLConnection *pConn, BOOL bCheckVer = FALSE)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
CESEConnection *pConn2 = (CESEConnection *)pConn;
|
|
|
|
JET_SESID sesid = pConn2->GetSessionID();
|
|
JET_ERR err = JET_errSuccess;
|
|
JET_DBID dbid;
|
|
CLASSMAP cm;
|
|
char *pDB = GetAnsiString(pTemplate->rgProperties[4].vValue.bstrVal);
|
|
if (!pDB)
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
IWbemClassObject *pTest = NULL;
|
|
CDeleteMe <char> d (pDB);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
LPWSTR lpDatabase = pTemplate->rgProperties[4].vValue.bstrVal;
|
|
err = JetAttachDatabase( sesid, pDB, 0 ) ;
|
|
if (err < JET_errSuccess)
|
|
{
|
|
if (err == JET_errDatabaseCorrupted)
|
|
{
|
|
// DeleteDatabase(lpDatabase);
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
return hr;
|
|
}
|
|
|
|
err = JetCreateDatabase(sesid, pDB, NULL, &dbid, 0);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
pConn2->SetDBID(dbid);
|
|
}
|
|
else
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
return hr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = JetOpenDatabase (sesid, pDB, NULL, &dbid, 0);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (bCheckVer)
|
|
{
|
|
BOOL bDelete = CheckVersion(sesid, dbid, CURRENT_DB_VERSION);
|
|
|
|
// Ensure that this database is the proper version
|
|
JET_TABLEID tableid;
|
|
|
|
err = JetOpenTable (sesid, dbid, "ClassMap", NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
JET_COLUMNDEF columnDef;
|
|
|
|
// If the table exists but the column doesn't, this is
|
|
// an old beta version, and we need to delete it and
|
|
// start over.
|
|
|
|
err = JetGetColumnInfo(sesid, dbid, "ClassMap", "ClassBlob",
|
|
&columnDef, sizeof(JET_COLUMNDEF), 0);
|
|
if (err != JET_errSuccess)
|
|
bDelete = TRUE;
|
|
JetCloseTable(sesid, tableid);
|
|
}
|
|
if (bDelete)
|
|
{
|
|
err = JetCloseDatabase(sesid, dbid, 0);
|
|
err = JetEndSession(sesid, 0);
|
|
err = JetTerm2(gJetInst, JET_bitTermComplete);
|
|
hr = DeleteDatabase(lpDatabase);
|
|
return WBEM_E_DATABASE_VER_MISMATCH;
|
|
}
|
|
}
|
|
pConn2->SetDBID(dbid);
|
|
}
|
|
else
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
// Initialize our data.
|
|
|
|
DWORD dwPos;
|
|
LPWSTR lpTableName = NULL;
|
|
|
|
// Create the tables.
|
|
|
|
err = JetBeginTransaction(sesid);
|
|
|
|
if (FAILED(hr = UpdateDBVersion(pConn, CURRENT_DB_VERSION)) ||
|
|
FAILED(hr = SetupObjectMapAccessor(pConn)) ||
|
|
FAILED(hr = SetupClassMapAccessor(pConn)) ||
|
|
FAILED(hr = SetupPropertyMapAccessor(pConn)) ||
|
|
FAILED(hr = SetupClassDataAccessor(pConn)) ||
|
|
FAILED(hr = SetupIndexDataAccessor(pConn, WMIDB_STORAGE_STRING, dwPos, &lpTableName))||
|
|
FAILED(hr = SetupClassKeysAccessor(pConn)))
|
|
goto Exit;
|
|
|
|
CDeleteMe<WCHAR> dmlpTableName( lpTableName );
|
|
|
|
hr = GetFirst_ClassMap(pConn, 1, cm);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
cm.Clear();
|
|
goto Exit;
|
|
}
|
|
|
|
// Default system classes.
|
|
|
|
if (FAILED(hr = InsertObjectMap(pConn, 1, L"meta_class", 3, L"meta_class", 0, 0, 0, 0, TRUE)) ||
|
|
FAILED(hr = InsertObjectMap(pConn, 2372429868687864876, L"__Namespace", 3, L"__Namespace", 0, 0, 0, 1, TRUE)) ||
|
|
FAILED(hr = InsertObjectMap(pConn, -1411745643584611171, L"root", 3, L"root", 0, 0, 0, 2372429868687864876, TRUE)) ||
|
|
FAILED(hr = InsertObjectMap(pConn, 3373910491091605771, L"__Instances", 3, L"__Instances", 0, 0, 0, 1, TRUE)) ||
|
|
FAILED(hr = InsertScopeMap_Internal(pConn, -1411745643584611171, L"root", 0)) ||
|
|
FAILED(hr = InsertObjectMap(pConn, -7316356768687527881, L"__Container_Association", 3, L"__Container_Association", 0, 0, 0, 1, TRUE)) ||
|
|
FAILED(hr = InsertClassMap(pConn, 1, L"meta_class", 0, 1, NULL, 0, TRUE)))
|
|
goto Exit;
|
|
|
|
// Repository-specific system classes
|
|
|
|
if (FAILED(GetFirst_ClassMap(pConn, 2372429868687864876, cm)))
|
|
{
|
|
_IWmiObject *pObj = NULL;
|
|
hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER,
|
|
IID__IWmiObject, (void **)&pObj);
|
|
CReleaseMe r (pObj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
VARIANT vTemp;
|
|
VariantInit(&vTemp);
|
|
vTemp.bstrVal = SysAllocString(L"__Namespace");
|
|
vTemp.vt = VT_BSTR;
|
|
|
|
pObj->Put(L"__Class", 0, &vTemp, CIM_STRING);
|
|
VariantClear(&vTemp);
|
|
pObj->Put(L"Name", 0, NULL, CIM_STRING);
|
|
IWbemQualifierSet *pQS = NULL;
|
|
|
|
hr = pObj->GetPropertyQualifierSet(L"Name", &pQS);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
vTemp.boolVal = 1;
|
|
vTemp.vt = VT_BOOL;
|
|
pQS->Put(L"key", &vTemp, 0);
|
|
pQS->Release();
|
|
VariantClear(&vTemp);
|
|
}
|
|
|
|
BYTE buff[128];
|
|
DWORD dwLen = 0;
|
|
hr = pObj->Unmerge(0, 128, &dwLen, &buff);
|
|
|
|
if (dwLen > 0)
|
|
{
|
|
BYTE *pBuff = new BYTE [dwLen];
|
|
if (pBuff)
|
|
{
|
|
CDeleteMe <BYTE> r2 (pBuff);
|
|
DWORD dwLen1;
|
|
hr = pObj->Unmerge(0, dwLen, &dwLen1, pBuff);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = InsertClassMap(pConn, 2372429868687864876, L"__Namespace", 1, 2372429868687864876, pBuff, dwLen, TRUE);
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
}
|
|
cm.Clear();
|
|
|
|
if (FAILED(GetFirst_ClassMap(pConn, 3373910491091605771, cm)))
|
|
{
|
|
_IWmiObject *pObj = NULL;
|
|
hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER,
|
|
IID__IWmiObject, (void **)&pObj);
|
|
CReleaseMe r (pObj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
VARIANT vTemp;
|
|
VariantInit(&vTemp);
|
|
vTemp.bstrVal = SysAllocString(L"__Instances");
|
|
vTemp.vt = VT_BSTR;
|
|
|
|
pObj->Put(L"__Class", 0, &vTemp, CIM_STRING);
|
|
VariantClear(&vTemp);
|
|
pObj->Put(L"ClassName", 0, NULL, CIM_STRING);
|
|
IWbemQualifierSet *pQS = NULL;
|
|
|
|
hr = pObj->GetPropertyQualifierSet(L"ClassName", &pQS);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
vTemp.boolVal = 1;
|
|
vTemp.vt = VT_BOOL;
|
|
pQS->Put(L"key", &vTemp, 0);
|
|
pQS->Release();
|
|
VariantClear(&vTemp);
|
|
}
|
|
|
|
BYTE buff[128];
|
|
DWORD dwLen = 0;
|
|
|
|
hr = pObj->Unmerge(0, 128, &dwLen, &buff);
|
|
|
|
if (dwLen > 0)
|
|
{
|
|
BYTE *pBuff = new BYTE [dwLen];
|
|
if (pBuff)
|
|
{
|
|
CDeleteMe <BYTE> r2 (pBuff);
|
|
DWORD dwLen1;
|
|
hr = pObj->Unmerge(0, dwLen, &dwLen1, pBuff);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = InsertClassMap(pConn, 3373910491091605771, L"__Instances", 1, 3373910491091605771, pBuff, dwLen, TRUE);
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
}
|
|
cm.Clear();
|
|
|
|
if (FAILED(GetFirst_ClassMap(pConn, -7316356768687527881, cm)))
|
|
{
|
|
_IWmiObject *pObj = NULL;
|
|
hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER,
|
|
IID__IWmiObject, (void **)&pObj);
|
|
CReleaseMe r (pObj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
VARIANT vTemp;
|
|
VariantInit(&vTemp);
|
|
vTemp.bstrVal = SysAllocString(L"__Container_Association");
|
|
vTemp.vt = VT_BSTR;
|
|
|
|
pObj->Put(L"__Class", 0, &vTemp, CIM_STRING);
|
|
VariantClear(&vTemp);
|
|
pObj->Put(L"Containee", 0, NULL, CIM_REFERENCE);
|
|
pObj->Put(L"Container", 0, NULL, CIM_REFERENCE);
|
|
|
|
IWbemQualifierSet *pQS = NULL;
|
|
hr = pObj->GetPropertyQualifierSet(L"Containee", &pQS);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
vTemp.boolVal = 1;
|
|
vTemp.vt = VT_BOOL;
|
|
pQS->Put(L"key", &vTemp, 0);
|
|
pQS->Release();
|
|
VariantClear(&vTemp);
|
|
}
|
|
hr = pObj->GetPropertyQualifierSet(L"Container", &pQS);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
vTemp.boolVal = 1;
|
|
vTemp.vt = VT_BOOL;
|
|
pQS->Put(L"key", &vTemp, 0);
|
|
pQS->Release();
|
|
VariantClear(&vTemp);
|
|
}
|
|
|
|
BYTE buff[128];
|
|
DWORD dwLen = 0;
|
|
|
|
hr = pObj->Unmerge(0, 128, &dwLen, &buff);
|
|
|
|
if (dwLen > 0)
|
|
{
|
|
BYTE *pBuff;
|
|
pBuff = new BYTE [dwLen];
|
|
if (pBuff)
|
|
{
|
|
CDeleteMe <BYTE> r2 (pBuff);
|
|
DWORD dwLen1;
|
|
hr = pObj->Unmerge(0, dwLen, &dwLen1, pBuff);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = InsertClassMap(pConn, -7316356768687527881, L"__Container_Association", 1, -7316356768687527881, pBuff, dwLen, TRUE);
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
}
|
|
cm.Clear();
|
|
|
|
// Properties for default classes
|
|
|
|
DWORD iWaste = 0, dwPropID = 0;
|
|
|
|
if (FAILED(hr = InsertPropertyMap(pConn, dwPropID, 2372429868687864876, 1, 8, L"Name", 4, TRUE)) ||
|
|
FAILED(hr = InsertClassKeys(pConn, 2372429868687864876, dwPropID)) ||
|
|
FAILED(hr = InsertPropertyMap(pConn, iWaste, 3373910491091605771, 1, 8, L"ClassName", 4, TRUE)) ||
|
|
FAILED(hr = InsertClassKeys(pConn, 3373910491091605771, iWaste)) ||
|
|
FAILED(hr = InsertPropertyMap(pConn, iWaste, -7316356768687527881, 4, 102, L"Containee", 4, TRUE)) ||
|
|
FAILED(hr = InsertClassKeys(pConn, -7316356768687527881, iWaste)) ||
|
|
FAILED(hr = InsertPropertyMap(pConn, iWaste, -7316356768687527881, 4, 102, L"Container", 4, TRUE)) ||
|
|
FAILED(hr = InsertClassKeys(pConn, -7316356768687527881, iWaste)) ||
|
|
FAILED(hr = InsertClassData_Internal(pConn, -1411745643584611171, dwPropID, 0, 0, 2372429868687864876,
|
|
L"root", 0, 0, 4, 0, 0, FALSE)) ||
|
|
FAILED(hr = InsertIndexData (pConn, -1411745643584611171, dwPropID, 0, L"root", 0, 0, 1)))
|
|
goto Exit;
|
|
|
|
// System properties. Including them in the schema makes them queriable.
|
|
|
|
hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IWbemClassObject, (void **)&pTest);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CReleaseMe r (pTest);
|
|
BSTR strName;
|
|
CIMTYPE cimtype;
|
|
|
|
hr = pTest->BeginEnumeration(0);
|
|
while (pTest->Next(0, &strName, NULL, &cimtype, NULL) == S_OK)
|
|
{
|
|
DWORD dwStorageType = 0;
|
|
CFreeMe f1 (strName);
|
|
DWORD dwFlags = REPDRVR_FLAG_SYSTEM;
|
|
|
|
CIMTYPE ct = cimtype & 0xFFF;
|
|
bool bArray = (cimtype & CIM_FLAG_ARRAY)? true: false;
|
|
|
|
if (bArray)
|
|
dwFlags |= REPDRVR_FLAG_ARRAY;
|
|
|
|
if (!_wcsicmp(strName, L"__Path") ||
|
|
!_wcsicmp(strName, L"__RelPath") ||
|
|
!_wcsicmp(strName, L"__Class") ||
|
|
!_wcsicmp(strName, L"__SuperClass") ||
|
|
!_wcsicmp(strName, L"__Dynasty") ||
|
|
!_wcsicmp(strName, L"__Derivation") ||
|
|
!_wcsicmp(strName, L"__Version") ||
|
|
!_wcsicmp(strName, L"__Genus") ||
|
|
!_wcsicmp(strName, L"__Property_Count") ||
|
|
!_wcsicmp(strName, L"__Server") ||
|
|
!_wcsicmp(strName, L"__Namespace"))
|
|
dwStorageType = WMIDB_STORAGE_COMPACT;
|
|
else
|
|
dwStorageType = GetStorageType(ct, bArray);
|
|
|
|
if (FAILED(hr = InsertPropertyMap(pConn, iWaste, 1, dwStorageType, ct, strName, dwFlags, TRUE)))
|
|
goto Exit;
|
|
}
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
Exit:
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
JetCommitTransaction(sesid, 0);
|
|
}
|
|
else
|
|
JetRollback(sesid, 0);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLConnCache::FinalRollback
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLConnCache::FinalRollback(CSQLConnection *pConn)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Rollback this transaction and set Thread ID to zero
|
|
|
|
CESEConnection *pConn2 = (CESEConnection *)pConn;
|
|
CWmiESETransaction *pTrans = pConn2->m_pTrans;
|
|
if (pTrans)
|
|
{
|
|
hr = pTrans->Abort();
|
|
delete pTrans;
|
|
}
|
|
|
|
pConn2->m_pTrans = NULL;
|
|
pConn2->m_bInUse = false;
|
|
pConn2->m_tCreateTime = time(0); // We don't want to delete it immediately.
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLConnCache::FinalCommit
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLConnCache::FinalCommit(CSQLConnection *pConn)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Commit this transaction and erase the ThreadID
|
|
// from this connection.
|
|
|
|
CESEConnection *pConn2 = (CESEConnection *)pConn;
|
|
CWmiESETransaction *pTrans = pConn2->m_pTrans;
|
|
|
|
if (pTrans)
|
|
hr = pTrans->Commit();
|
|
|
|
pConn2->m_tCreateTime = time(0); // We don't want to delete it immediately.
|
|
delete pTrans;
|
|
pConn2->m_pTrans = NULL;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLConnCache::ReleaseConnection
|
|
//
|
|
//***************************************************************************
|
|
HRESULT CSQLConnCache::ReleaseConnection(CSQLConnection *_pConn,
|
|
HRESULT retcode, BOOL bDistributed)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
DWORD dwNumFreed = 0;
|
|
|
|
// If we're shutting down, the connection will be released anyway.
|
|
|
|
if (m_dwStatus == WBEM_E_SHUTTING_DOWN)
|
|
{
|
|
hr = FinalRollback(_pConn);
|
|
((CESEConnection *)_pConn)->m_bInUse = false;
|
|
return WBEM_E_SHUTTING_DOWN;
|
|
}
|
|
|
|
CRepdrvrCritSec r (&m_cs);
|
|
|
|
for (int i = m_Conns.size() -1; i >=0; i--)
|
|
{
|
|
CSQLConnection *pConn = m_Conns.at(i);
|
|
if (pConn)
|
|
{
|
|
CESEConnection *pConn2 = (CESEConnection *)pConn;
|
|
if (_pConn == pConn)
|
|
{
|
|
if (FAILED(retcode))
|
|
{
|
|
// If this is a distributed transaction,
|
|
// they decide on the final commit.
|
|
|
|
if (!bDistributed)
|
|
{
|
|
hr = FinalRollback(pConn);
|
|
|
|
if (retcode == WBEM_E_CRITICAL_ERROR ||
|
|
retcode == WBEM_E_INVALID_QUERY ||
|
|
retcode == WBEM_E_OUT_OF_MEMORY)
|
|
{
|
|
delete pConn2; // This deletes the transaction.
|
|
pConn2 = NULL;
|
|
|
|
m_Conns.erase(&m_Conns.at(i));
|
|
DEBUGTRACE((LOG_WBEMCORE, "THREAD %ld deleted ESE connection %X. Number of connections = %ld\n",
|
|
GetCurrentThreadId(), pConn, m_Conns.size()));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If this is a distributed transaction,
|
|
// they decide on the final commit.
|
|
|
|
if (!bDistributed)
|
|
hr = FinalCommit(pConn);
|
|
}
|
|
|
|
if (pConn2)
|
|
pConn2->m_bInUse = false;
|
|
dwNumFreed++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Notify waiting threads that there is
|
|
// an open connection.
|
|
// =====================================
|
|
|
|
{
|
|
CRepdrvrCritSec r (&m_cs);
|
|
for (int i = 0; i < m_WaitQueue.size(); i++)
|
|
{
|
|
if (i >= dwNumFreed)
|
|
break;
|
|
|
|
HANDLE hTemp = m_WaitQueue.at(i);
|
|
SetEvent(hTemp);
|
|
|
|
DEBUGTRACE((LOG_WBEMCORE, "Thread %ld released a connection...\n", GetCurrentThreadId()));
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLConnCache::Shutdown
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLConnCache::Shutdown()
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
JET_ERR err = 0;
|
|
time_t tStart = time(0), tEnd = time(0) + 5;
|
|
m_dwStatus = WBEM_E_SHUTTING_DOWN;
|
|
|
|
if (m_bInit)
|
|
{
|
|
CRepdrvrCritSec r (&m_cs);
|
|
|
|
int iConnectionsLeftOpen = m_Conns.size();
|
|
while (iConnectionsLeftOpen)
|
|
{
|
|
{
|
|
CRepdrvrCritSec r (&m_cs);
|
|
iConnectionsLeftOpen = 0;
|
|
|
|
for (int i = m_Conns.size()-1; i >= 0; i--)
|
|
{
|
|
// Give threads up to 5 seconds to shut down.
|
|
|
|
if (((CESEConnection *)m_Conns.at(i))->m_bInUse)
|
|
iConnectionsLeftOpen++;
|
|
else if (!((CESEConnection *)m_Conns.at(i))->m_bInUse)
|
|
{
|
|
delete m_Conns.at(i);
|
|
m_Conns.erase(&m_Conns.at(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!iConnectionsLeftOpen)
|
|
break;
|
|
else
|
|
{
|
|
if (tEnd >= tStart)
|
|
{
|
|
Sleep(100); // Check every 50 ms.
|
|
tStart = time(0);
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (iConnectionsLeftOpen)
|
|
{
|
|
CRepdrvrCritSec r (&m_cs);
|
|
for (int i = m_Conns.size()-1; i >= 0; i--)
|
|
{
|
|
// Give threads up to 5 seconds to shut down.
|
|
|
|
if (((CESEConnection *)m_Conns.at(i))->m_bInUse)
|
|
{
|
|
CESEConnection *pConn2 = (CESEConnection *)m_Conns.at(i);
|
|
if (pConn2)
|
|
{
|
|
DEBUGTRACE((LOG_WBEMCORE,
|
|
"CONNECTION: #%ld \n"
|
|
" In Use = %ld\n"
|
|
" Creation time = %ld\n"
|
|
" Thread ID = %ld\n",
|
|
i,
|
|
((CESEConnection *)pConn2)->m_bInUse,
|
|
((CESEConnection *)pConn2)->m_tCreateTime,
|
|
((CESEConnection *)pConn2)->m_dwThreadId));
|
|
}
|
|
}
|
|
}
|
|
m_Conns.clear();
|
|
}
|
|
|
|
DEBUGTRACE((LOG_WBEMCORE, "Database shutting down in response to a Shutdown command.\n"));
|
|
if (iConnectionsLeftOpen)
|
|
ERRORTRACE((LOG_WBEMCORE, "%ld connections left open. All threads did not release their connections!\n",
|
|
iConnectionsLeftOpen));
|
|
|
|
// _ASSERT(iConnectionsLeftOpen == 0, "Shutdown was unable to close all db connections.");
|
|
|
|
err = JetTerm2(gJetInst, JET_bitTermComplete);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
gJetInst = NULL;
|
|
m_bInit = FALSE;
|
|
}
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// Startup
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT Startup(CSQLConnection *pConn)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
hr = CleanAutoDeletes(pConn);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLConnCache::DeleteUnusedConnections
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLConnCache::DeleteUnusedConnections(BOOL bDeadOnly)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
|
|
CRepdrvrCritSec r (&m_cs);
|
|
|
|
for (int i = m_Conns.size()-1; i >= 0; i--)
|
|
{
|
|
CESEConnection *pConn = (CESEConnection *)m_Conns.at(i);
|
|
if (pConn)
|
|
{
|
|
if (!pConn->m_bInUse)
|
|
{
|
|
BOOL bDelete = FALSE;
|
|
if (bDeadOnly)
|
|
{
|
|
if (dwThreadId != pConn->m_dwThreadId)
|
|
{
|
|
HANDLE hTemp = OpenThread(STANDARD_RIGHTS_REQUIRED, FALSE, pConn->m_dwThreadId);
|
|
if (hTemp)
|
|
{
|
|
CloseHandle(hTemp);
|
|
time_t tNow = time(0);
|
|
if ((tNow - pConn->m_tCreateTime) > 60)
|
|
bDelete = TRUE;
|
|
}
|
|
else
|
|
bDelete = TRUE;
|
|
}
|
|
}
|
|
else
|
|
bDelete = TRUE;
|
|
|
|
if (bDelete)
|
|
{
|
|
delete pConn; // This deletes the transaction, which should be NULL.
|
|
pConn = NULL;
|
|
m_Conns.erase(&m_Conns.at(i));
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
if (!bDeadOnly)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLConnCache::GetConnection
|
|
//
|
|
//***************************************************************************
|
|
HRESULT CSQLConnCache::GetConnection(CSQLConnection **ppConn, BOOL bTransacted, BOOL bDistributed,
|
|
DWORD dwTimeOutSecs)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
bool bFound = false;
|
|
JET_ERR err = 0;
|
|
BOOL bStartUp = FALSE;
|
|
DWORD dwThreadId = GetCurrentThreadId();
|
|
|
|
if (!ppConn)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
if (m_dwStatus == WBEM_E_SHUTTING_DOWN)
|
|
return WBEM_E_SHUTTING_DOWN;
|
|
|
|
if (m_WaitQueue.size() && dwTimeOutSecs > 0)
|
|
goto Queue;
|
|
|
|
// Look for any connection that belongs
|
|
// to a thread that has gone bye-bye
|
|
// and kill it.
|
|
// ===================================
|
|
|
|
{
|
|
CRepdrvrCritSec r (&m_cs);
|
|
DeleteUnusedConnections(TRUE);
|
|
|
|
// See if there are any free connections.
|
|
// ======================================
|
|
|
|
if (m_Conns.size() > 0)
|
|
{
|
|
for (int i = 0; i < m_Conns.size(); i++)
|
|
{
|
|
CESEConnection *pConn = (CESEConnection *)m_Conns.at(i);
|
|
if (pConn)
|
|
{
|
|
time_t tTemp = time(0);
|
|
|
|
if (!pConn->m_bInUse)
|
|
{
|
|
// We need
|
|
// to reuse the same connection,
|
|
// since Jet is apartment-model
|
|
// ============================
|
|
|
|
if (dwThreadId == pConn->m_dwThreadId)
|
|
{
|
|
pConn->m_bInUse = true;
|
|
pConn->m_tCreateTime = time(0);
|
|
*ppConn = pConn;
|
|
bFound = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// If there were no free connections, try and obtain a new one.
|
|
// ============================================================
|
|
{
|
|
if (!bFound && (m_Conns.size() < m_dwMaxNumConns))
|
|
{
|
|
if (!m_bInit)
|
|
{
|
|
// Get a new JET_INSTANCE from the parameters
|
|
// in m_pPropSet
|
|
// m_sDatabaseName = database name
|
|
// m_pPropSet[1].bstrVal = user name
|
|
// m_pPropSet[2].bstrVal = password
|
|
|
|
LPWSTR lpPath = GetPath(m_sDatabaseName);
|
|
if (lpPath)
|
|
{
|
|
CDeleteMe <wchar_t> d (lpPath);
|
|
char * pPath2 = GetAnsiString(lpPath);
|
|
if (!pPath2)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
CDeleteMe <char> d3 (pPath2);
|
|
if (pPath2)
|
|
{
|
|
DWORD dwVal = 1024;
|
|
|
|
if ((err = JetSetSystemParameter (&gJetInst, 0, JET_paramMaxSessions, 25, NULL)) != JET_errSuccess ||
|
|
(err = JetSetSystemParameter (&gJetInst, 0, JET_paramCacheSizeMin, 100, NULL)) != JET_errSuccess ||
|
|
(err = JetSetSystemParameter (&gJetInst, 0, JET_paramCacheSizeMax, 1024, NULL)) != JET_errSuccess ||
|
|
(err = JetSetSystemParameter (&gJetInst, 0, JET_paramEventLogCache, 65536, NULL)) != JET_errSuccess ||
|
|
(err = JetSetSystemParameter (&gJetInst, 0, JET_paramCircularLog, TRUE, NULL)) != JET_errSuccess ||
|
|
(err = JetSetSystemParameter( &gJetInst, 0, JET_paramSystemPath, 0, pPath2)) != JET_errSuccess ||
|
|
(err = JetSetSystemParameter( &gJetInst, 0, JET_paramTempPath, 0, pPath2)) != JET_errSuccess ||
|
|
(err = JetSetSystemParameter( &gJetInst, 0, JET_paramLogFilePath, 0, pPath2)) != JET_errSuccess ||
|
|
(err = JetSetSystemParameter( &gJetInst, 0, JET_paramMaxVerPages, dwVal, NULL)) != JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
else
|
|
{
|
|
err = JetInit(&gJetInst);
|
|
//if (err < JET_errSuccess)
|
|
// {
|
|
// hr = DeleteDatabase(m_sDatabaseName);
|
|
// if (SUCCEEDED(hr))
|
|
// err = JetInit(&gJetInst);
|
|
// }
|
|
|
|
if (err == JET_errSuccess)
|
|
{
|
|
m_bInit = TRUE;
|
|
bStartUp = TRUE;
|
|
}
|
|
else
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
|
|
// If that worked, get a new session,
|
|
// and attach the current DB.
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
char *pUser = GetAnsiString(m_pPropSet->rgProperties[2].vValue.bstrVal);
|
|
char *pPwd = GetAnsiString(m_pPropSet->rgProperties[3].vValue.bstrVal);
|
|
CDeleteMe <char> d3 (pUser), d4 (pPwd);
|
|
|
|
if (!pUser || !pPwd)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
JET_SESID session;
|
|
err = JetBeginSession(gJetInst, &session, pUser, pPwd);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
CSQLConnection *pConn = (CSQLConnection *)new CESEConnection(session);
|
|
if (pConn)
|
|
{
|
|
hr = AttachESEDatabase(m_pPropSet, pConn, bStartUp);
|
|
if (FAILED(hr) && hr == WBEM_E_DATABASE_VER_MISMATCH)
|
|
{
|
|
if ((JetInit(&gJetInst) != JET_errSuccess) ||
|
|
(JetBeginSession(gJetInst, &session, pUser, pPwd) != JET_errSuccess) ||
|
|
!((CESEConnection *)pConn)->SetSessionID(session) ||
|
|
(FAILED(hr = AttachESEDatabase(m_pPropSet, pConn, bStartUp))))
|
|
hr = WBEM_E_DATABASE_VER_MISMATCH;
|
|
}
|
|
if (SUCCEEDED(hr) && bStartUp)
|
|
hr = Startup(pConn);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
((CESEConnection *)pConn)->m_bInUse = true;
|
|
((CESEConnection *)pConn)->m_tCreateTime = time(0);
|
|
((CESEConnection *)pConn)->m_dwThreadId = dwThreadId;
|
|
|
|
m_Conns.push_back(pConn);
|
|
DEBUGTRACE((LOG_WBEMCORE, "THREAD %ld obtained new ESE connection %X, session %X. Number of connections = %ld\n",
|
|
dwThreadId, pConn, &session, m_Conns.size()));
|
|
#ifdef _DEBUG_CONNS
|
|
for (int i = 0; i < m_Conns.size()-1; i++)
|
|
{
|
|
CESEConnection *pConn2 = (CESEConnection *)m_Conns.at(i);
|
|
if (pConn)
|
|
{
|
|
DEBUGTRACE((LOG_WBEMCORE,
|
|
"CONNECTION: #%ld \n"
|
|
" In Use = %ld\n"
|
|
" Creation time = %ld\n"
|
|
" Thread ID = %ld\n",
|
|
i,
|
|
((CESEConnection *)pConn2)->m_bInUse,
|
|
((CESEConnection *)pConn2)->m_tCreateTime,
|
|
((CESEConnection *)pConn2)->m_dwThreadId));
|
|
|
|
}
|
|
}
|
|
#endif
|
|
*ppConn = pConn;
|
|
}
|
|
else
|
|
delete pConn;
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
int iNumConns = m_Conns.size();
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && *ppConn != NULL && (bTransacted || bDistributed))
|
|
{
|
|
CESEConnection *pConn = (CESEConnection *)*ppConn;
|
|
CWmiESETransaction *pTrans = pConn->GetTransaction();
|
|
if (!pTrans)
|
|
{
|
|
pTrans = new CWmiESETransaction(((CESEConnection *)pConn)->GetSessionID());
|
|
pConn->SetTransaction(pTrans);
|
|
}
|
|
|
|
if (pTrans)
|
|
pTrans->StartTransaction();
|
|
}
|
|
}
|
|
|
|
Queue:
|
|
|
|
// Otherwise, wait for a connection to be released.
|
|
// ================================================
|
|
|
|
if (!*ppConn && (m_Conns.size() >= m_dwMaxNumConns || m_WaitQueue.size()) && dwTimeOutSecs > 0)
|
|
{
|
|
DEBUGTRACE((LOG_WBEMCORE, "WARNING: >> Number of ESE connections exceeded (%ld). Thread %ld is waiting on one to be released...\n",
|
|
m_Conns.size(), dwThreadId));
|
|
BOOL bWait = FALSE;
|
|
|
|
HANDLE hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
if (hThreadEvent != INVALID_HANDLE_VALUE)
|
|
{
|
|
CRepdrvrCritSec r (&m_cs);
|
|
// Reserve our spot in the queue so we get the very next connection.
|
|
m_WaitQueue.push_back(hThreadEvent);
|
|
|
|
// Check for a free connection one last time.
|
|
|
|
hr = DeleteUnusedConnections(FALSE);
|
|
if (SUCCEEDED(hr))
|
|
hr = GetConnection(ppConn, bTransacted, bDistributed, 0);
|
|
else
|
|
bWait = TRUE;
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
if (bWait)
|
|
{
|
|
if (WbemWaitForSingleObject(hThreadEvent, 30*1000) == WAIT_OBJECT_0)
|
|
{
|
|
hr = GetConnection(ppConn, bTransacted, bDistributed, 0);
|
|
if (SUCCEEDED(hr))
|
|
DEBUGTRACE((LOG_WBEMCORE, "Thread %ld obtained a connection.\n", dwThreadId));
|
|
else
|
|
DEBUGTRACE((LOG_WBEMCORE, "Thread %ld failed to obtain a connection.\n", dwThreadId));
|
|
}
|
|
else
|
|
hr = WBEM_E_SERVER_TOO_BUSY;
|
|
}
|
|
|
|
// Remove ourself from the queue
|
|
// This will happen whether the GetConnection
|
|
// succeeded or failed
|
|
// ==========================================
|
|
|
|
{
|
|
CRepdrvrCritSec r (&m_cs);
|
|
for (int i = 0; i < m_WaitQueue.size(); i++)
|
|
{
|
|
if (hThreadEvent == m_WaitQueue.at(i))
|
|
{
|
|
m_WaitQueue.erase(&m_WaitQueue.at(i));
|
|
break;
|
|
}
|
|
}
|
|
CloseHandle(hThreadEvent);
|
|
}
|
|
|
|
CloseHandle(hThreadEvent);
|
|
}
|
|
|
|
if (!*ppConn && SUCCEEDED(hr))
|
|
{
|
|
DEBUGTRACE((LOG_WBEMCORE, "Thread %ld was unable to obtain a connection.\n", dwThreadId));
|
|
hr = WBEM_E_SERVER_TOO_BUSY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecute::GetWMIError
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecute::GetWMIError(long ErrorID)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
switch(ErrorID)
|
|
{
|
|
case JET_errSuccess:
|
|
case JET_errRecordDeleted:
|
|
hr = WBEM_S_NO_ERROR;
|
|
break;
|
|
case JET_wrnNyi:
|
|
hr = E_NOTIMPL;
|
|
break;
|
|
case JET_errOutOfMemory:
|
|
case JET_errOutOfDatabaseSpace:
|
|
case JET_errOutOfCursors:
|
|
case JET_errOutOfBuffers:
|
|
case JET_errOutOfFileHandles:
|
|
case JET_errVersionStoreOutOfMemory:
|
|
case JET_errCurrencyStackOutOfMemory:
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
break;
|
|
case JET_errInvalidParameter:
|
|
case JET_errKeyTooBig:
|
|
case JET_errInvalidGrbit:
|
|
case JET_errInvalidName:
|
|
hr = WBEM_E_INVALID_PARAMETER;
|
|
break;
|
|
case JET_errRecordNotDeleted:
|
|
case JET_errWriteConflict:
|
|
hr = WBEM_E_FAILED;
|
|
break;
|
|
case JET_errRecordNotFound:
|
|
case JET_errDatabaseNotFound:
|
|
case JET_errNoCurrentRecord:
|
|
case JET_errFileNotFound:
|
|
hr = WBEM_E_NOT_FOUND;
|
|
break;
|
|
case JET_errNTSystemCallFailed:
|
|
case JET_errLogFileCorrupt:
|
|
case JET_errDatabaseInconsistent:
|
|
case JET_errConsistentTimeMismatch:
|
|
case JET_errDatabasePatchFileMismatch:
|
|
case JET_errInvalidDatabaseId:
|
|
case JET_errDiskIO:
|
|
case JET_errInvalidPath:
|
|
case JET_errInvalidSystemPath:
|
|
case JET_errInvalidLogDirectory:
|
|
case JET_errInvalidDatabase:
|
|
case JET_errInvalidFilename:
|
|
case JET_errPageSizeMismatch:
|
|
hr = WBEM_E_CRITICAL_ERROR;
|
|
break;
|
|
case JET_errFileAccessDenied:
|
|
case JET_errPermissionDenied:
|
|
hr = WBEM_E_ACCESS_DENIED;
|
|
break;
|
|
case JET_errOutOfSessions:
|
|
case JET_errInvalidSesid:
|
|
hr = WBEM_E_CONNECTION_FAILED;
|
|
break;
|
|
case JET_errQueryNotSupported:
|
|
case JET_errSQLLinkNotSupported:
|
|
hr = WBEM_E_INVALID_QUERY;
|
|
break;
|
|
default:
|
|
if (ErrorID > 0)
|
|
hr = WBEM_S_NO_ERROR;
|
|
else
|
|
hr = WBEM_E_INVALID_QUERY;
|
|
}
|
|
|
|
if (FAILED(hr) && hr != WBEM_E_NOT_FOUND)
|
|
ERRORTRACE((LOG_WBEMCORE, "Jet returned the following error: %ld\n", ErrorID));
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT SetInArray (VARIANT &vOriginal, DWORD iPos, VARIANT &vNew, CIMTYPE ct)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
if (vOriginal.vt & CIM_FLAG_ARRAY)
|
|
{
|
|
SAFEARRAY *pArray = V_ARRAY(&vOriginal);
|
|
SAFEARRAYBOUND aBounds[1];
|
|
long lLBound, lUBound;
|
|
DWORD Comp = (DWORD)iPos+1;
|
|
|
|
SafeArrayGetLBound(pArray, 1, &lLBound);
|
|
SafeArrayGetUBound(pArray, 1, &lUBound);
|
|
|
|
lUBound -= lLBound;
|
|
lUBound += 1;
|
|
|
|
if (Comp > lUBound)
|
|
{
|
|
aBounds[0].cElements = Comp;
|
|
aBounds[0].lLbound = 0;
|
|
|
|
SAFEARRAY *pNew = SafeArrayCreate(vNew.vt, 1, aBounds);
|
|
if (pNew)
|
|
{
|
|
for ( int i = 0; i < lUBound; i++ )
|
|
{
|
|
long lTemp[1];
|
|
lTemp[0] = i;
|
|
|
|
if ( (ct & 0xFFF) == CIM_STRING ||
|
|
(ct & 0xFFF) == CIM_DATETIME ||
|
|
(ct & 0xFFF) == CIM_REFERENCE )
|
|
{
|
|
BSTR bstr;
|
|
|
|
if ( SUCCEEDED(SafeArrayGetElement( pArray,
|
|
lTemp,
|
|
&bstr) ) )
|
|
{
|
|
SafeArrayPutElement( pNew, lTemp, bstr );
|
|
SysFreeString( bstr );
|
|
}
|
|
}
|
|
else if ( (ct & 0xFFF) == CIM_OBJECT )
|
|
{
|
|
|
|
IUnknown* pObj;
|
|
|
|
if ( SUCCEEDED(SafeArrayGetElement( pArray,
|
|
lTemp,
|
|
&pObj) ) )
|
|
{
|
|
SafeArrayPutElement( pNew, lTemp, pObj );
|
|
pObj->Release();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
double dbVal;
|
|
|
|
if ( SUCCEEDED(SafeArrayGetElement( pArray,
|
|
lTemp,
|
|
&dbVal ) ) )
|
|
{
|
|
SafeArrayPutElement( pNew, lTemp, &dbVal );
|
|
}
|
|
}
|
|
}
|
|
|
|
SafeArrayDestroy(pArray);
|
|
pArray = pNew;
|
|
}
|
|
}
|
|
|
|
hr = PutVariantInArray(&pArray, iPos, &vNew);
|
|
if (SUCCEEDED(hr))
|
|
V_ARRAY(&vOriginal) = pArray;
|
|
|
|
}
|
|
else
|
|
{
|
|
VariantClear(&vOriginal);
|
|
|
|
// This is a new object.
|
|
SAFEARRAYBOUND aBounds[1];
|
|
aBounds[0].cElements = iPos+1;
|
|
aBounds[0].lLbound = 0;
|
|
SAFEARRAY* pArray = SafeArrayCreate(vNew.vt, 1, aBounds);
|
|
if (pArray)
|
|
{
|
|
hr = PutVariantInArray(&pArray, iPos, &vNew);
|
|
vOriginal.vt = VT_ARRAY|vNew.vt;
|
|
V_ARRAY(&vOriginal) = pArray;
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetObjectData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetObjectData(CSQLConnection *pConn, IWbemClassObject *pNewObj, IWmiDbSession *pSession, CSchemaCache *pSchema,
|
|
CLASSDATA cd, BOOL bBlobData, BOOL &bBigText, BOOL *bObject=NULL, BOOL bNoDefaults=FALSE)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
_bstr_t sPropName;
|
|
DWORD dwStorage, dwCIMType, dwPropFlags;
|
|
VARIANT vValue;
|
|
VariantInit(&vValue);
|
|
vValue.vt = VT_NULL;
|
|
wchar_t wTemp[455];
|
|
BOOL bSkip = FALSE;
|
|
int iLen = 0;
|
|
SQL_ID dRefId, dClassId;
|
|
|
|
if (bObject)
|
|
*bObject = FALSE;
|
|
|
|
dRefId = cd.dRefId;
|
|
|
|
hr = pSchema->GetPropertyInfo (cd.iPropertyId, &sPropName, NULL, &dwStorage,
|
|
&dwCIMType, &dwPropFlags);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (bNoDefaults && !(dwPropFlags & REPDRVR_FLAG_NONPROP))
|
|
return WBEM_S_NO_ERROR;
|
|
|
|
if (!(cd.iFlags & ESE_FLAG_NULL))
|
|
{
|
|
switch(dwStorage)
|
|
{
|
|
case WMIDB_STORAGE_REFERENCE: // Reference or object
|
|
case WMIDB_STORAGE_STRING:
|
|
if (bBlobData)
|
|
{
|
|
if ((dwCIMType == CIM_STRING || dwCIMType == CIM_REFERENCE)
|
|
&& cd.dwBufferLen > 0)
|
|
{
|
|
vValue.vt = VT_BSTR;
|
|
vValue.bstrVal = SysAllocString((LPWSTR)cd.pBuffer);
|
|
if (vValue.bstrVal)
|
|
iLen = wcslen(vValue.bstrVal);
|
|
}
|
|
else
|
|
{
|
|
vValue.vt = VT_NULL;
|
|
iLen = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (cd.sPropertyStringValue != NULL)
|
|
{
|
|
vValue.bstrVal = SysAllocString(cd.sPropertyStringValue);
|
|
if (vValue.bstrVal)
|
|
{
|
|
vValue.vt = VT_BSTR;
|
|
iLen = wcslen(vValue.bstrVal);
|
|
bBigText = IsTruncated(vValue.bstrVal, 127);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
case WMIDB_STORAGE_NUMERIC:
|
|
// Set in one of the kajillion numeric types...
|
|
if (dwCIMType == CIM_UINT64 || dwCIMType == CIM_SINT64)
|
|
{
|
|
wchar_t wTemp[50];
|
|
swprintf(wTemp, L"%I64d", cd.dPropertyNumericValue);
|
|
vValue.bstrVal = SysAllocString(wTemp);
|
|
vValue.vt = VT_BSTR;
|
|
}
|
|
else if (dwCIMType == CIM_BOOLEAN)
|
|
{
|
|
vValue.boolVal = (BOOL) cd.dPropertyNumericValue;
|
|
vValue.vt = VT_BOOL;
|
|
}
|
|
else
|
|
{
|
|
vValue.lVal = (DWORD) cd.dPropertyNumericValue;
|
|
vValue.vt = VT_I4;
|
|
}
|
|
|
|
break;
|
|
case WMIDB_STORAGE_REAL:
|
|
// Set as 32 or 64-bit real
|
|
|
|
if (dwCIMType == CIM_REAL32)
|
|
{
|
|
vValue.fltVal = (float)cd.rPropertyRealValue;
|
|
vValue.vt = VT_R4;
|
|
}
|
|
else if (dwCIMType == CIM_REAL64)
|
|
{
|
|
vValue.fltVal = (double)cd.rPropertyRealValue;
|
|
vValue.vt = VT_R8;
|
|
}
|
|
|
|
break;
|
|
case WMIDB_STORAGE_IMAGE:
|
|
if (dwCIMType != CIM_OBJECT)
|
|
{
|
|
if (cd.dwBufferLen > 0)
|
|
{
|
|
long why[1];
|
|
unsigned char t;
|
|
SAFEARRAYBOUND aBounds[1];
|
|
aBounds[0].cElements = cd.dwBufferLen;
|
|
aBounds[0].lLbound = 0;
|
|
SAFEARRAY* pArray = SafeArrayCreate(VT_UI1, 1, aBounds);
|
|
vValue.vt = VT_I1;
|
|
for (int i = 0; i < cd.dwBufferLen; i++)
|
|
{
|
|
why[0] = i;
|
|
t = cd.pBuffer[i];
|
|
hr = SafeArrayPutElement(pArray, why, &t);
|
|
}
|
|
vValue.vt = VT_ARRAY|VT_UI1;
|
|
V_ARRAY(&vValue) = pArray;
|
|
dwCIMType |= CIM_FLAG_ARRAY;
|
|
}
|
|
}
|
|
else
|
|
vValue.vt = VT_NULL;
|
|
break;
|
|
default:
|
|
hr = WBEM_E_NOT_SUPPORTED;
|
|
break;
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
goto Exit;
|
|
}
|
|
|
|
// If this is an object (not a reference),
|
|
// then we need to Get the object and set it in
|
|
// the variant. Otherwise, the variant is simply
|
|
// the string path to the object.
|
|
// ===============================================
|
|
|
|
if (dwCIMType == CIM_OBJECT)
|
|
{
|
|
if (bObject)
|
|
{
|
|
*bObject = TRUE;
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
if (!bBlobData)
|
|
{
|
|
IWmiDbHandle *pHand = NULL;
|
|
|
|
if (vValue.vt == VT_BSTR)
|
|
{
|
|
hr = ((CWmiDbSession *)pSession)->GetObject_Internal((LPWSTR)vValue.bstrVal, (DWORD)0,
|
|
(DWORD)WMIDB_HANDLE_TYPE_COOKIE, NULL, &pHand, pConn);
|
|
CReleaseMe r4 (pHand);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IWbemClassObject *pEmbed = NULL;
|
|
hr = ((CWmiDbHandle *)pHand)->QueryInterface_Internal(pConn, (void **)&pEmbed);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
VariantClear(&vValue);
|
|
V_UNKNOWN(&vValue) = (IUnknown *)pEmbed;
|
|
vValue.vt = VT_UNKNOWN;
|
|
// VariantClear will release this, right?
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_IWmiObject *pNew = NULL;
|
|
hr = ConvertBlobToObject (pNewObj, cd.pBuffer, cd.dwBufferLen, &pNew);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
VariantClear(&vValue);
|
|
V_UNKNOWN(&vValue) = (IUnknown *)pNew;
|
|
vValue.vt = VT_UNKNOWN;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// For array properties, what we actually need to do is
|
|
// see if the property exists already. If not, we
|
|
// initialize the safe array and add the first element.
|
|
// If so, we simply set the value in the existing array.
|
|
// ======================================================
|
|
|
|
if (dwPropFlags & REPDRVR_FLAG_ARRAY && (dwStorage != WMIDB_STORAGE_IMAGE))
|
|
{
|
|
dwCIMType |= CIM_FLAG_ARRAY;
|
|
|
|
VARIANT vTemp;
|
|
CClearMe c (&vTemp);
|
|
long lTemp;
|
|
CIMTYPE cimtype;
|
|
if (SUCCEEDED(pNewObj->Get(sPropName, 0, &vTemp, &cimtype, &lTemp)))
|
|
{
|
|
hr = SetInArray(vTemp, cd.iArrayPos, vValue, cimtype);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pNewObj->Put(sPropName, 0, &vTemp, dwCIMType);
|
|
bSkip = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!(dwPropFlags & REPDRVR_FLAG_QUALIFIER) &&
|
|
!(dwPropFlags & REPDRVR_FLAG_IN_PARAM) &&
|
|
!(dwPropFlags & REPDRVR_FLAG_OUT_PARAM) &&
|
|
!bSkip)
|
|
{
|
|
if (wcslen(sPropName) == 127)
|
|
{
|
|
pNewObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
|
|
BSTR strName = NULL;
|
|
|
|
while (pNewObj->Next(0, &strName, NULL, NULL, NULL) == S_OK)
|
|
{
|
|
CFreeMe f (strName);
|
|
if (!_wcsnicmp(strName, sPropName, 127))
|
|
sPropName = strName;
|
|
}
|
|
}
|
|
hr = pNewObj->Put(sPropName, 0, &vValue, dwCIMType);
|
|
}
|
|
|
|
// If this is a qualifier on a class, get the qualifier set and set the value.
|
|
else if (dwPropFlags & REPDRVR_FLAG_QUALIFIER )
|
|
{
|
|
if (dRefId != 0)
|
|
{
|
|
_bstr_t sProp2;
|
|
DWORD dwFlags2, dwRefID;
|
|
|
|
hr = pSchema->GetPropertyInfo (dRefId, &sProp2, NULL, NULL,
|
|
NULL, &dwFlags2, NULL, NULL, &dwRefID);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (wcslen(sPropName) == 127)
|
|
{
|
|
pNewObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
|
|
BSTR strName = NULL;
|
|
|
|
while (pNewObj->Next(0, &strName, NULL, NULL, NULL) == S_OK)
|
|
{
|
|
CFreeMe f (strName);
|
|
if (!_wcsnicmp(strName, sProp2, 127))
|
|
sProp2 = strName;
|
|
}
|
|
}
|
|
|
|
// This is a property qualifier. See if its a property or a method.
|
|
// and get all the pertinent info.
|
|
|
|
// This is a qualifier on a method parameter.
|
|
if (dwFlags2 & REPDRVR_FLAG_IN_PARAM ||
|
|
dwFlags2 & REPDRVR_FLAG_OUT_PARAM)
|
|
{
|
|
IWbemClassObject *pIn = NULL;
|
|
IWbemClassObject *pOut = NULL;
|
|
IWbemQualifierSet *pQS = NULL;
|
|
|
|
_bstr_t sProp3;
|
|
|
|
hr = pSchema->GetPropertyInfo (dwRefID, &sProp3);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pNewObj->GetMethod(sProp3, 0, &pIn, &pOut);
|
|
CReleaseMe r5 (pIn), r6 (pOut);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (dwFlags2 & REPDRVR_FLAG_IN_PARAM && pIn)
|
|
hr = pIn->GetPropertyQualifierSet(sProp2, &pQS);
|
|
else if (dwFlags2 & REPDRVR_FLAG_OUT_PARAM && pOut)
|
|
hr = pOut->GetPropertyQualifierSet(sProp2, &pQS);
|
|
|
|
if (pQS)
|
|
{
|
|
CReleaseMe r7 (pQS);
|
|
if (!_wcsicmp(sPropName, L"id"))
|
|
sPropName = L"repdrvr_id"; // Sneaky business.
|
|
// Because we can't set method parameters incrementally,
|
|
// we need to store the real position IDs as a different
|
|
// name and switch them back when we're done...
|
|
|
|
if (dwPropFlags & REPDRVR_FLAG_ARRAY)
|
|
{
|
|
VARIANT vTemp;
|
|
BOOL bExists = FALSE;
|
|
CClearMe c (&vTemp);
|
|
hr = pQS->Get(sPropName, 0, &vTemp, 0);
|
|
if (vTemp.vt & CIM_FLAG_ARRAY)
|
|
bExists = TRUE;
|
|
hr = SetInArray(vTemp, cd.iArrayPos, vValue, dwCIMType);
|
|
hr = pQS->Put(sPropName, &vTemp, cd.iFlags);
|
|
}
|
|
else
|
|
hr = pQS->Put(sPropName, &vValue, cd.iFlags);
|
|
|
|
hr = pNewObj->PutMethod(sProp3, 0, pIn, pOut);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// This is a qualifier on a method.
|
|
|
|
else if (dwFlags2 & REPDRVR_FLAG_METHOD)
|
|
{
|
|
IWbemQualifierSet *pQS = NULL;
|
|
hr = pNewObj->GetMethodQualifierSet(sProp2, &pQS);
|
|
CReleaseMe r4 (pQS);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (dwPropFlags & REPDRVR_FLAG_ARRAY)
|
|
{
|
|
VARIANT vTemp;
|
|
CClearMe c (&vTemp);
|
|
BOOL bExists = FALSE;
|
|
hr = pQS->Get(sPropName, 0, &vTemp, 0);
|
|
if (vTemp.vt & CIM_FLAG_ARRAY)
|
|
bExists = TRUE;
|
|
hr = SetInArray(vTemp, cd.iArrayPos, vValue, dwCIMType);
|
|
hr = pQS->Put(sPropName, &vTemp, cd.iFlags);
|
|
}
|
|
else
|
|
hr = pQS->Put(sPropName, &vValue, cd.iFlags);
|
|
}
|
|
}
|
|
// This is a qualifier on a property.
|
|
else
|
|
{
|
|
IWbemQualifierSet *pQS = NULL;
|
|
hr = pNewObj->GetPropertyQualifierSet(sProp2, &pQS);
|
|
CReleaseMe r4 (pQS);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (dwPropFlags & REPDRVR_FLAG_ARRAY)
|
|
{
|
|
VARIANT vTemp;
|
|
CClearMe c (&vTemp);
|
|
BOOL bExists = FALSE;
|
|
hr = pQS->Get(sPropName, 0, &vTemp, 0);
|
|
if (vTemp.vt & CIM_FLAG_ARRAY)
|
|
bExists = TRUE;
|
|
hr = SetInArray(vTemp, cd.iArrayPos, vValue, dwCIMType);
|
|
hr = pQS->Put(sPropName, &vTemp, cd.iFlags);
|
|
}
|
|
else
|
|
hr = pQS->Put(sPropName, &vValue, cd.iFlags);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else // Its just a class/instance qualifier. Set it.
|
|
{
|
|
IWbemQualifierSet *pQS = NULL;
|
|
hr = pNewObj->GetQualifierSet(&pQS);
|
|
CReleaseMe r5 (pQS);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (dwPropFlags & REPDRVR_FLAG_ARRAY)
|
|
{
|
|
VARIANT vTemp;
|
|
CClearMe c (&vTemp);
|
|
BOOL bExists = FALSE;
|
|
hr = pQS->Get(sPropName, 0, &vTemp, 0);
|
|
if (vTemp.vt & CIM_FLAG_ARRAY)
|
|
bExists = TRUE;
|
|
hr = SetInArray(vTemp, cd.iArrayPos, vValue, dwCIMType);
|
|
hr = pQS->Put(sPropName, &vTemp, cd.iFlags);
|
|
}
|
|
else
|
|
hr = pQS->Put(sPropName, &vValue, cd.iFlags);
|
|
}
|
|
}
|
|
}
|
|
else if (dwPropFlags & REPDRVR_FLAG_METHOD)
|
|
{
|
|
// This is a method. Skip it.
|
|
|
|
}
|
|
else if (dwPropFlags & REPDRVR_FLAG_IN_PARAM ||
|
|
dwPropFlags & REPDRVR_FLAG_OUT_PARAM )
|
|
{
|
|
_bstr_t sProp2;
|
|
IWbemClassObject *pTemp = NULL;
|
|
|
|
hr = pSchema->GetPropertyInfo (dRefId, &sProp2);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IWbemClassObject *pOther = NULL;
|
|
|
|
if (dwPropFlags & REPDRVR_FLAG_IN_PARAM)
|
|
hr = pNewObj->GetMethod(sProp2, 0, &pTemp, &pOther);
|
|
else
|
|
hr = pNewObj->GetMethod(sProp2, 0, &pOther, &pTemp);
|
|
CReleaseMe r1 (pTemp), r2 (pOther);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (!pTemp)
|
|
{
|
|
hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IWbemClassObject, (void **)&pTemp);
|
|
VARIANT vTemp;
|
|
CClearMe c (&vTemp);
|
|
vTemp.bstrVal = SysAllocString(L"__Parameters");
|
|
vTemp.vt = VT_BSTR;
|
|
pTemp->Put(L"__Class", NULL, &vTemp, CIM_STRING);
|
|
}
|
|
pTemp->Put(sPropName, 0, &vValue, dwCIMType);
|
|
|
|
VARIANT vTemp;
|
|
CClearMe c2 (&vTemp);
|
|
long lNumProps = 0;
|
|
pTemp->Get(L"__Property_Count", NULL, &vTemp, NULL, NULL);
|
|
lNumProps = vTemp.lVal;
|
|
if (pOther)
|
|
{
|
|
VARIANT vTemp2;
|
|
CClearMe c2 (&vTemp2);
|
|
pOther->Get(L"__Property_Count", NULL, &vTemp2, NULL, NULL);
|
|
lNumProps+= vTemp2.lVal;
|
|
}
|
|
|
|
if (_wcsicmp(sPropName, L"ReturnValue"))
|
|
{
|
|
IWbemQualifierSet *pQS = NULL;
|
|
pTemp->GetPropertyQualifierSet(sPropName, &pQS);
|
|
CReleaseMe r5 (pQS);
|
|
if (pQS)
|
|
{
|
|
V_I4(&vTemp) = lNumProps - 1;
|
|
vTemp.vt = VT_I4;
|
|
|
|
pQS->Put(L"id", &vTemp, 0);
|
|
}
|
|
}
|
|
|
|
if (dwPropFlags & REPDRVR_FLAG_IN_PARAM)
|
|
hr = pNewObj->PutMethod(sProp2, 0, pTemp, pOther);
|
|
else
|
|
hr = pNewObj->PutMethod(sProp2, 0, pOther, pTemp);
|
|
|
|
hr = pSchema->SetAuxiliaryPropertyInfo(cd.iPropertyId, L"", dRefId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
VariantClear(&vValue);
|
|
return hr;
|
|
}
|
|
|
|
// structs for open rowsets.
|
|
|
|
//***************************************************************************
|
|
//
|
|
// AddColumnToTable
|
|
//
|
|
//***************************************************************************
|
|
|
|
// Helper functions for setting up reusable accessors.
|
|
|
|
HRESULT AddColumnToTable (CESEConnection *pConn, JET_TABLEID tableid, LPSTR lpTableName, LPWSTR lpColumnName,
|
|
DWORD _colid, DWORD datatype, DWORD options, DWORD prec, JET_COLUMNID *colid)
|
|
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
char *pColName = GetAnsiString(lpColumnName);
|
|
|
|
if (!pColName)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
CDeleteMe <char> d (pColName);
|
|
JET_COLUMNDEF columnDef;
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
err = JetGetColumnInfo(pConn->GetSessionID(), pConn->GetDBID(), lpTableName, pColName,
|
|
&columnDef, sizeof(JET_COLUMNDEF), 0);
|
|
|
|
if (err < JET_errSuccess)
|
|
{
|
|
columnDef.cp = 1200; // Unicode? Otherwise, its 1252.
|
|
columnDef.wCountry = 1;
|
|
columnDef.langid = 1033;
|
|
columnDef.wCollate = 0;
|
|
columnDef.cbStruct = sizeof(JET_COLUMNDEF);
|
|
|
|
columnDef.columnid = _colid;
|
|
columnDef.coltyp = datatype;
|
|
columnDef.grbit = options ;
|
|
columnDef.cbMax = prec;
|
|
err = JetAddColumn(pConn->GetSessionID(), tableid, pColName, &columnDef, "", 0, colid);
|
|
}
|
|
else
|
|
*colid = columnDef.columnid;
|
|
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdateDBVersion
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdateDBVersion (CSQLConnection *_pConn, DWORD iVersion)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
const LPSTR lpTbl = "DBVersion";
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_DBID dbid = pConn->GetDBID();
|
|
JET_TABLEID tableid;
|
|
|
|
JET_ERR err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"Version", 0, JET_coltypLong,
|
|
JET_bitColumnNotNULL, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// This is a one-row table.
|
|
err = JetMove(session, tableid, JET_MoveFirst, 0);
|
|
if (err >= JET_errSuccess)
|
|
err = JetPrepareUpdate(session, tableid, JET_prepReplace);
|
|
else
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, colid,
|
|
&iVersion, sizeof(DWORD), 0, NULL );
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
}
|
|
|
|
JetCloseTable(session, tableid);
|
|
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupObjectMapAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupObjectMapAccessor (CSQLConnection *_pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
const LPSTR lpTbl = "ObjectMap";
|
|
|
|
if (!pConn->GetTableID(L"ObjectMap"))
|
|
{
|
|
JET_SESID session;
|
|
JET_TABLEID tableid;
|
|
BOOL bCreate = FALSE;
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
JET_DBID dbid = pConn->GetDBID();
|
|
|
|
JET_ERR err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
CSQLExecute::GetWMIError(err);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
pConn->SetTableID(L"ObjectMap", tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
// Unfortunately, they don't support a numeric type,
|
|
// so we have to use currency.
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ObjectId", OBJECTMAP_COL_OBJECTID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, OBJECTMAP_COL_OBJECTID, colid);
|
|
else if (err != JET_errColumnDuplicate)
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ObjectPath", OBJECTMAP_COL_OBJECTPATH, JET_coltypText,
|
|
0, MAX_STRING_WIDTH, &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, OBJECTMAP_COL_OBJECTPATH, colid);
|
|
else if (err != JET_errColumnDuplicate)
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ObjectKey", OBJECTMAP_COL_OBJECTKEY, JET_coltypText,
|
|
0, MAX_STRING_WIDTH, &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, OBJECTMAP_COL_OBJECTKEY, colid);
|
|
else if (err != JET_errColumnDuplicate)
|
|
goto Exit;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ReferenceCount", OBJECTMAP_COL_REFERENCECOUNT, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, OBJECTMAP_COL_REFERENCECOUNT, colid);
|
|
else if (err != JET_errColumnDuplicate)
|
|
goto Exit;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ObjectState", OBJECTMAP_COL_OBJECTSTATE, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, OBJECTMAP_COL_OBJECTSTATE, colid);
|
|
else if (err != JET_errColumnDuplicate)
|
|
goto Exit;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ClassId", OBJECTMAP_COL_CLASSID, JET_coltypCurrency,
|
|
0, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, OBJECTMAP_COL_CLASSID, colid);
|
|
else if (err != JET_errColumnDuplicate)
|
|
goto Exit;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ObjectFlags", OBJECTMAP_COL_OBJECTFLAGS, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, OBJECTMAP_COL_OBJECTFLAGS, colid);
|
|
else if (err != JET_errColumnDuplicate)
|
|
goto Exit;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ObjectScopeId", OBJECTMAP_COL_OBJECTSCOPEID, JET_coltypCurrency,
|
|
0, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, OBJECTMAP_COL_OBJECTSCOPEID, colid);
|
|
else if (err != JET_errColumnDuplicate)
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "ObjectMap_PK", JET_bitIndexPrimary | JET_bitIndexUnique,"+ObjectId\0", 11, 100);
|
|
if (err >= JET_errSuccess || err == JET_errIndexHasPrimary)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "ObjectScopeId_idx", JET_bitIndexDisallowNull ,"+ObjectScopeId\0", 16, 100);
|
|
if (err >= JET_errSuccess|| err == JET_errIndexDuplicate)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "ObjectClassId_idx", JET_bitIndexDisallowNull ,"+ClassId\0", 10, 100);
|
|
if (err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
}
|
|
}
|
|
|
|
if (err >= JET_errSuccess && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupObjectMapAccessor(_pConn);
|
|
}
|
|
}
|
|
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetObjectMapData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetObjectMapData (CSQLConnection *_pConn, JET_SESID session, JET_TABLEID tableid,
|
|
OBJECTMAP &oj)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
oj.Clear();
|
|
unsigned long lLen;
|
|
wchar_t buff[1024];
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
oj.dObjectId = 0;
|
|
|
|
JET_ERR err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTID),
|
|
&oj.dObjectId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTKEY),
|
|
buff, MAX_STRING_WIDTH, &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (lLen)
|
|
{
|
|
buff[lLen/2] = L'\0';
|
|
oj.sObjectKey = SysAllocString(buff);
|
|
if (wcslen(buff) && !oj.sObjectKey)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto exit;
|
|
}
|
|
}
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTPATH),
|
|
buff, MAX_STRING_WIDTH, &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (lLen)
|
|
{
|
|
buff[lLen/2] = L'\0';
|
|
oj.sObjectPath = SysAllocString(buff);
|
|
if (wcslen(buff) && !oj.sObjectPath)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
oj.Clear();
|
|
goto exit;
|
|
}
|
|
}
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_REFERENCECOUNT),
|
|
&oj.iRefCount, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_CLASSID),
|
|
&oj.dClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTFLAGS),
|
|
&oj.iObjectFlags, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTSCOPEID),
|
|
&oj.dObjectScopeId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTSTATE),
|
|
&oj.iObjectState, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// OpenEnum_ObjectMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT OpenEnum_ObjectMap (CSQLConnection *_pConn, OBJECTMAP &oj)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupObjectMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ObjectMap");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ObjectMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMove(session, tableid, JET_MoveFirst, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetObjectMapData(pConn, session, tableid, oj);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ObjectMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ObjectMap (CSQLConnection *_pConn, SQL_ID dObjectId, OBJECTMAP &oj)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupObjectMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ObjectMap");
|
|
|
|
// Use the default index
|
|
// Grab the first row,
|
|
// and stuff it into the OBJECTMAP object.
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ObjectMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
hr = GetObjectMapData(pConn, session, tableid, oj);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ObjectMapByScope
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ObjectMapByScope (CSQLConnection *_pConn, SQL_ID dScopeId, OBJECTMAP &oj,
|
|
DWORD seektype = JET_bitSeekEQ)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupObjectMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ObjectMap");
|
|
|
|
// Use the default index
|
|
// Grab the first row,
|
|
// and stuff it into the OBJECTMAP object.
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ObjectScopeId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dScopeId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, seektype );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (seektype == JET_bitSeekEQ)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dScopeId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
}
|
|
else if (seektype == JET_bitSeekLT || seektype == JET_bitSeekLE )
|
|
{
|
|
err = JetMakeKey(session, tableid, &dScopeId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeUpperLimit);
|
|
}
|
|
if (err == JET_errSuccess)
|
|
hr = GetObjectMapData(pConn, session, tableid, oj);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ObjectMapByClass
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ObjectMapByClass (CSQLConnection *_pConn, SQL_ID dClassId, OBJECTMAP &oj)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupObjectMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ObjectMap");
|
|
|
|
// Use the default index
|
|
// Grab the first row,
|
|
// and stuff it into the OBJECTMAP object.
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ObjectClassId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dClassId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dClassId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetObjectMapData(pConn, session, tableid, oj);
|
|
}
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_ObjectMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_ObjectMap (CSQLConnection *_pConn, OBJECTMAP &oj)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
oj.Clear();
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ObjectMap");
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetObjectMapData(pConn, session, tableid, oj);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdateObjectMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdateObjectMap (CSQLConnection *_pConn, OBJECTMAP oj, BOOL bDelete = FALSE)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupObjectMapAccessor(pConn);
|
|
JET_ERR err = JET_errSuccess;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ObjectMap");
|
|
|
|
err = JetSetCurrentIndex(session, tableid, "ObjectMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &oj.dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepReplace);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (oj.sObjectPath)
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTPATH),
|
|
oj.sObjectPath, wcslen(oj.sObjectPath)*2+2, 0, NULL );
|
|
else
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTPATH),
|
|
NULL, 0, 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_CLASSID),
|
|
&oj.dClassId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTSCOPEID),
|
|
&oj.dObjectScopeId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
|
|
if (oj.sObjectKey)
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTKEY),
|
|
oj.sObjectKey, wcslen(oj.sObjectKey)*2+2, 0, NULL);
|
|
else
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTKEY),
|
|
NULL, 0, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_REFERENCECOUNT),
|
|
&oj.iRefCount, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTFLAGS),
|
|
&oj.iObjectFlags, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTSTATE),
|
|
&oj.iObjectState, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
|
|
if (bDelete)
|
|
err = JetDelete(session, tableid);
|
|
else
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertObjectMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertObjectMap(CSQLConnection *_pConn, SQL_ID dObjectId, LPCWSTR lpKey,
|
|
DWORD iState, LPCWSTR lpObjectPath, SQL_ID dScopeID, DWORD iClassFlags,
|
|
DWORD iRefCount, SQL_ID dClassId, BOOL bInsert)
|
|
{
|
|
|
|
DEBUGTRACE((LOG_WBEMCORE, "InsertObjectMap %S\n", lpObjectPath));
|
|
|
|
HRESULT hr = 0;
|
|
JET_ERR err = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupObjectMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
OBJECTMAP oj;
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ObjectMap");
|
|
|
|
if (FAILED(GetFirst_ObjectMap(_pConn, dObjectId, oj)))
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTID), &dObjectId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTPATH), lpObjectPath, wcslen(lpObjectPath)*2+2, 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_CLASSID), &dClassId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTSCOPEID), &dScopeID, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTKEY), lpKey, wcslen(lpKey)*2+2, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_REFERENCECOUNT), &iRefCount, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTFLAGS), &iClassFlags, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, OBJECTMAP_COL_OBJECTSTATE), &iState, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
else if (!bInsert)
|
|
{
|
|
oj.Clear();
|
|
oj.dObjectId = dObjectId;
|
|
oj.dClassId = dClassId;
|
|
oj.sObjectPath = SysAllocString(lpObjectPath);
|
|
oj.sObjectKey = SysAllocString(lpKey);
|
|
if (!oj.sObjectPath || !oj.sObjectKey)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
oj.Clear();
|
|
goto Exit;
|
|
}
|
|
oj.iRefCount = iRefCount;
|
|
oj.iObjectFlags = iClassFlags;
|
|
oj.dObjectScopeId = dScopeID;
|
|
oj.iObjectState = iState;
|
|
|
|
hr = UpdateObjectMap(pConn, oj, FALSE);
|
|
oj.Clear();
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupScopeMapAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupScopeMapAccessor (CSQLConnection *_pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
if (!pConn->GetTableID(L"ScopeMap"))
|
|
{
|
|
JET_SESID session;
|
|
JET_TABLEID tableid;
|
|
JET_DBID dbid;
|
|
const LPSTR lpTbl = "ScopeMap";
|
|
BOOL bCreate = FALSE;
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
dbid = pConn->GetDBID();
|
|
|
|
JET_ERR err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
pConn->SetTableID(L"ScopeMap", tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ObjectId", SCOPEMAP_COL_OBJECTID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, SCOPEMAP_COL_OBJECTID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ScopePath", SCOPEMAP_COL_SCOPEPATH, JET_coltypLongBinary,
|
|
0, 0, &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, SCOPEMAP_COL_SCOPEPATH, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ParentId", SCOPEMAP_COL_PARENTID, JET_coltypCurrency,
|
|
0, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, SCOPEMAP_COL_PARENTID, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "ScopeMap_PK", JET_bitIndexPrimary | JET_bitIndexUnique,"+ObjectId\0", 11, 100);
|
|
if ((err >= JET_errSuccess || err == JET_errIndexHasPrimary) && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupScopeMapAccessor(_pConn);
|
|
}
|
|
}
|
|
if (err == JET_errIndexHasPrimary)
|
|
err = 0;
|
|
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
Exit:
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetScopeMapData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetScopeMapData (CSQLConnection *_pConn, JET_SESID session, JET_TABLEID tableid,
|
|
SCOPEMAP &sm)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
unsigned long lLen;
|
|
wchar_t buff[1024];
|
|
BYTE buff2[1024];
|
|
sm.Clear();
|
|
|
|
JET_ERR err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, SCOPEMAP_COL_OBJECTID),
|
|
&sm.dObjectId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, SCOPEMAP_COL_SCOPEPATH),
|
|
buff2, MAX_STRING_WIDTH, &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (lLen)
|
|
{
|
|
BYTE *pBuff = new BYTE [lLen];
|
|
if (pBuff)
|
|
{
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, SCOPEMAP_COL_SCOPEPATH),
|
|
pBuff, lLen, &lLen, JET_bitRetrieveCopy, NULL);
|
|
sm.sScopePath = SysAllocString((LPWSTR)pBuff);
|
|
if (!sm.sScopePath)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto exit;
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
}
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, SCOPEMAP_COL_PARENTID),
|
|
&sm.dParentId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// OpenEnum_ScopeMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT OpenEnum_ScopeMap (CSQLConnection *_pConn, SCOPEMAP &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupScopeMapAccessor(pConn);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ScopeMap");
|
|
|
|
// Use the default index
|
|
// Grab the first row,
|
|
// and stuff it into the SCOPEMAP object.
|
|
JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ScopeMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMove(session, tableid, JET_MoveFirst, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetScopeMapData(pConn, session, tableid, cd);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ScopeMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ScopeMap (CSQLConnection *_pConn, SQL_ID dScopeId, SCOPEMAP &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupScopeMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ScopeMap");
|
|
|
|
// Use the default index
|
|
// Grab the first row,
|
|
// and stuff it into the SCOPEMAP object.
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ScopeMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dScopeId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dScopeId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (err == JET_errSuccess)
|
|
hr = GetScopeMapData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_ScopeMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_ScopeMap (CSQLConnection *_pConn, SCOPEMAP &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
cd.Clear();
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ScopeMap");
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetScopeMapData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdateScopeMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdateScopeMap (CSQLConnection *_pConn, SCOPEMAP cd, BOOL bDelete = FALSE)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = 0;
|
|
hr = SetupScopeMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ScopeMap");
|
|
|
|
err = JetSetCurrentIndex(session, tableid, "ScopeMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &cd.dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepReplace);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, SCOPEMAP_COL_PARENTID),
|
|
&cd.dParentId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
|
|
if (cd.sScopePath)
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, SCOPEMAP_COL_SCOPEPATH),
|
|
cd.sScopePath, wcslen(cd.sScopePath)*2+2, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
|
|
if (bDelete)
|
|
err = JetDelete(session, tableid);
|
|
else
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
if (bDelete && hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertScopeMap_Internal
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertScopeMap_Internal(CSQLConnection *_pConn, SQL_ID dObjectId, LPCWSTR lpPath, SQL_ID dParentId)
|
|
{
|
|
JET_ERR err = 0;
|
|
HRESULT hr = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupScopeMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
SCOPEMAP oj;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ScopeMap");
|
|
|
|
if (FAILED(GetFirst_ScopeMap(_pConn, dObjectId, oj)))
|
|
{
|
|
int iLen = 2;
|
|
BYTE *pBuff = (BYTE *)lpPath;
|
|
if (lpPath)
|
|
{
|
|
iLen += wcslen(lpPath)*2;
|
|
}
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, SCOPEMAP_COL_OBJECTID),
|
|
&dObjectId, sizeof(__int64), 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, SCOPEMAP_COL_SCOPEPATH),
|
|
pBuff, iLen, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, SCOPEMAP_COL_PARENTID),
|
|
&dParentId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
oj.Clear();
|
|
}
|
|
else
|
|
{
|
|
oj.Clear();
|
|
oj.dObjectId = dObjectId;
|
|
oj.dParentId = dParentId;
|
|
oj.sScopePath = SysAllocString(lpPath);
|
|
if (!oj.sScopePath)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
hr = UpdateScopeMap(pConn, oj, FALSE);
|
|
SysFreeString(oj.sScopePath); // The buffer is released by the caller.
|
|
}
|
|
|
|
}
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteScopeMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteScopeMap(CSQLConnection *_pConn, SQL_ID dObjectId)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupScopeMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ScopeMap");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ScopeMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetDelete(session, tableid);
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupClassMapAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupClassMapAccessor (CSQLConnection *_pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
if (!pConn->GetTableID(L"ClassMap"))
|
|
{
|
|
JET_SESID session;
|
|
JET_TABLEID tableid;
|
|
JET_DBID dbid;
|
|
const LPSTR lpTbl = "ClassMap";
|
|
BOOL bCreate = FALSE;
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
dbid = pConn->GetDBID();
|
|
|
|
JET_ERR err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
pConn->SetTableID(L"ClassMap", tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ClassId", CLASSMAP_COL_CLASSID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSMAP_COL_CLASSID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ClassName", CLASSMAP_COL_CLASSNAME, JET_coltypText,
|
|
0, MAX_STRING_WIDTH, &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSMAP_COL_CLASSNAME, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"SuperClassId", CLASSMAP_COL_SUPERCLASSID, JET_coltypCurrency,
|
|
0, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSMAP_COL_SUPERCLASSID, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"DynastyId", CLASSMAP_COL_DYNASTYID, JET_coltypCurrency,
|
|
0, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSMAP_COL_DYNASTYID, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ClassBlob", CLASSMAP_COL_CLASSBUFFER, JET_coltypLongBinary,
|
|
0, 0, &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSMAP_COL_CLASSBUFFER, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "ClassMap_PK", JET_bitIndexPrimary | JET_bitIndexUnique,"+ClassId\0", 10, 100);
|
|
if (err >= JET_errSuccess || err == JET_errIndexHasPrimary)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "SuperClassId_idx", JET_bitIndexDisallowNull ,"+SuperClassId\0", 15, 100);
|
|
if (err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
err = JetCreateIndex(session, tableid, "DynastyId_idx", JET_bitIndexDisallowNull, "+DynastyId\0", 12, 80);
|
|
if (err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
err = JetCreateIndex(session, tableid, "ClassName_idx", JET_bitIndexDisallowNull, "+ClassName\0", 12, 80);
|
|
if (err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
}
|
|
if (err >= JET_errSuccess && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupClassMapAccessor(_pConn);
|
|
}
|
|
}
|
|
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
Exit:
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetClassMapData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetClassMapData (CSQLConnection *_pConn, JET_SESID session, JET_TABLEID tableid,
|
|
CLASSMAP &oj)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
unsigned long lLen;
|
|
wchar_t buff[1024];
|
|
BYTE buff2[1024];
|
|
oj.dClassId = 0;
|
|
oj.dSuperClassId = 0;
|
|
oj.dDynastyId = 0;
|
|
|
|
oj.Clear();
|
|
|
|
JET_ERR err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_CLASSID),
|
|
&oj.dClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_CLASSNAME),
|
|
buff, MAX_STRING_WIDTH, &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (lLen)
|
|
{
|
|
buff[lLen/2] = L'\0';
|
|
oj.sClassName = SysAllocString(buff);
|
|
if (!oj.sClassName)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto exit;
|
|
}
|
|
}
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_SUPERCLASSID),
|
|
&oj.dSuperClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_DYNASTYID),
|
|
&oj.dDynastyId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_CLASSBUFFER),
|
|
buff2, MAX_STRING_WIDTH, &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (lLen)
|
|
{
|
|
oj.dwBufferLen = lLen;
|
|
BYTE *pBuff = new BYTE [lLen];
|
|
if (pBuff)
|
|
{
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_CLASSBUFFER),
|
|
pBuff, lLen, &oj.dwBufferLen, JET_bitRetrieveCopy, NULL);
|
|
oj.pClassBuffer = pBuff;
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
oj.Clear();
|
|
goto exit;
|
|
}
|
|
}
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// OpenEnum_ClassMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT OpenEnum_ClassMap (CSQLConnection *_pConn, CLASSMAP &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupClassMapAccessor(pConn);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassMap");
|
|
|
|
// Use the default index
|
|
// Grab the first row,
|
|
// and stuff it into the OBJECTMAP object.
|
|
JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ClassMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMove(session, tableid, JET_MoveFirst, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetClassMapData(pConn, session, tableid, cd);
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassMap (CSQLConnection *_pConn, SQL_ID dClassId, CLASSMAP &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupClassMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassMap");
|
|
|
|
// Use the default index
|
|
// Grab the first row,
|
|
// and stuff it into the OBJECTMAP object.
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ClassMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dClassId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dClassId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (err == JET_errSuccess)
|
|
hr = GetClassMapData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassMapBySuperClass
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassMapBySuperClass (CSQLConnection *_pConn, SQL_ID dSuperClassId, CLASSMAP &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupClassMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassMap");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "SuperClassId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dSuperClassId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dSuperClassId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetClassMapData(pConn, session, tableid, cd);
|
|
}
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassMapByDynasty
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassMapByDynasty (CSQLConnection *_pConn, SQL_ID dDynastyId, CLASSMAP &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupClassMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassMap");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "DynastyId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dDynastyId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dDynastyId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetClassMapData(pConn, session, tableid, cd);
|
|
}
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassMapByName
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassMapByName (CSQLConnection *_pConn, LPCWSTR lpName, CLASSMAP &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
if (!lpName)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupClassMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassMap");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ClassName_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, lpName, wcslen(lpName)*2+2, JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, lpName, wcslen(lpName)*2+2, JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetClassMapData(pConn, session, tableid, cd);
|
|
}
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_ClassMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_ClassMap (CSQLConnection *_pConn, CLASSMAP &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
cd.Clear();
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassMap");
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetClassMapData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdateClassMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdateClassMap (CSQLConnection *_pConn, CLASSMAP cd, BOOL bDelete = FALSE)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = 0;
|
|
hr = SetupClassMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassMap");
|
|
|
|
err = JetSetCurrentIndex(session, tableid, "ClassMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &cd.dClassId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepReplace);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_CLASSNAME),
|
|
cd.sClassName, wcslen(cd.sClassName)*2+2, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_SUPERCLASSID),
|
|
&cd.dSuperClassId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_DYNASTYID),
|
|
&cd.dDynastyId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
if (cd.dwBufferLen)
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_CLASSBUFFER),
|
|
cd.pClassBuffer, cd.dwBufferLen, 0, NULL);
|
|
else
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_CLASSBUFFER),
|
|
NULL, 0, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
if (bDelete)
|
|
err = JetDelete(session, tableid);
|
|
else
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertClassMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertClassMap(CSQLConnection *_pConn, SQL_ID dClassId, LPCWSTR lpClassName, SQL_ID dSuperClassId,
|
|
SQL_ID dDynasty, BYTE *pBuff, DWORD dwBufferLen, BOOL bInsert)
|
|
{
|
|
|
|
if (!dSuperClassId && dClassId != 1)
|
|
dSuperClassId = 1;
|
|
|
|
JET_ERR err = 0;
|
|
HRESULT hr = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupClassMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
CLASSMAP oj;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassMap");
|
|
|
|
if (FAILED(GetFirst_ClassMap(_pConn, dClassId, oj)))
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_CLASSID),
|
|
&dClassId, sizeof(__int64), 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_CLASSNAME),
|
|
lpClassName, wcslen(lpClassName)*2+2, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_SUPERCLASSID),
|
|
&dSuperClassId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_DYNASTYID),
|
|
&dDynasty, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSMAP_COL_CLASSBUFFER),
|
|
pBuff, dwBufferLen, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
oj.Clear();
|
|
}
|
|
else if (!bInsert)
|
|
{
|
|
oj.Clear();
|
|
oj.dClassId = dClassId;
|
|
oj.dSuperClassId = dSuperClassId;
|
|
oj.dDynastyId = dDynasty;
|
|
oj.sClassName = SysAllocString(lpClassName);
|
|
if (!oj.sClassName)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto Exit;
|
|
}
|
|
oj.pClassBuffer = pBuff;
|
|
oj.dwBufferLen = dwBufferLen;
|
|
|
|
hr = UpdateClassMap(pConn, oj, FALSE);
|
|
SysFreeString(oj.sClassName); // The buffer is released by the caller.
|
|
}
|
|
|
|
}
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupPropertyMapAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupPropertyMapAccessor (CSQLConnection *_pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
if (!pConn->GetTableID(L"PropertyMap"))
|
|
{
|
|
JET_SESID session;
|
|
JET_DBID dbid;
|
|
JET_TABLEID tableid;
|
|
const LPSTR lpTbl = "PropertyMap";
|
|
BOOL bCreate = FALSE;
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
dbid = pConn->GetDBID();
|
|
JET_ERR err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
pConn->SetTableID(L"PropertyMap", tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ClassId", PROPERTYMAP_COL_CLASSID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, PROPERTYMAP_COL_CLASSID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"PropertyId", PROPERTYMAP_COL_PROPERTYID, JET_coltypLong,
|
|
JET_bitColumnNotNULL|JET_bitColumnAutoincrement, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, PROPERTYMAP_COL_PROPERTYID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"StorageTypeId", PROPERTYMAP_COL_STORAGETYPEID, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, PROPERTYMAP_COL_STORAGETYPEID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"CIMTypeId", PROPERTYMAP_COL_CIMTYPEID, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, PROPERTYMAP_COL_CIMTYPEID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"PropertyName", PROPERTYMAP_COL_PROPERTYNAME, JET_coltypText,
|
|
JET_bitColumnNotNULL, MAX_STRING_WIDTH, &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, PROPERTYMAP_COL_PROPERTYNAME, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"Flags", PROPERTYMAP_COL_FLAGS, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, PROPERTYMAP_COL_FLAGS, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "PropertyMap_PK", JET_bitIndexPrimary | JET_bitIndexUnique,"+PropertyId\0", 13, 100);
|
|
if (err >= JET_errSuccess || err == JET_errIndexHasPrimary)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "ClassId_idx", JET_bitIndexDisallowNull ,"+ClassId\0", 10, 100);
|
|
if (err >= JET_errSuccess || err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
else
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
if (err >= JET_errSuccess && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupPropertyMapAccessor(_pConn);
|
|
}
|
|
}
|
|
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetPropertyMapData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetPropertyMapData (CSQLConnection *_pConn, JET_SESID session, JET_TABLEID tableid,
|
|
PROPERTYMAP &oj)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
oj.Clear();
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
unsigned long lLen;
|
|
wchar_t buff[1024];
|
|
oj.iPropertyId = 0;
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_PROPERTYID),
|
|
&oj.iPropertyId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_PROPERTYNAME),
|
|
buff, MAX_STRING_WIDTH, &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (lLen)
|
|
{
|
|
buff[lLen/2] = L'\0';
|
|
oj.sPropertyName = SysAllocString(buff);
|
|
if (!oj.sPropertyName)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto exit;
|
|
}
|
|
}
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_CLASSID),
|
|
&oj.dClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_STORAGETYPEID),
|
|
&oj.iStorageTypeId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_CIMTYPEID),
|
|
&oj.iCIMTypeId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_FLAGS),
|
|
&oj.iFlags, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_PropertyMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_PropertyMap (CSQLConnection *_pConn, DWORD iPropertyId, PROPERTYMAP &pm)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupPropertyMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"PropertyMap");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "PropertyMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
hr = GetPropertyMapData(pConn, session, tableid, pm);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_PropertyMapByClass
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_PropertyMapByClass (CSQLConnection *_pConn, SQL_ID dClassId, PROPERTYMAP &pm)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupPropertyMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"PropertyMap");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ClassId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dClassId, sizeof(SQL_ID), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dClassId, sizeof(SQL_ID), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
hr = GetPropertyMapData(pConn, session, tableid, pm);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_PropertyMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_PropertyMap (CSQLConnection *_pConn, PROPERTYMAP &pm)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
pm.Clear();
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = JET_errSuccess;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"PropertyMap");
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetPropertyMapData(pConn, session, tableid, pm);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdatePropertyMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdatePropertyMap(CSQLConnection *_pConn, PROPERTYMAP pm, BOOL bDelete = FALSE)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = 0;
|
|
hr = SetupPropertyMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"PropertyMap");
|
|
|
|
err = JetSetCurrentIndex(session, tableid, "PropertyMap_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &pm.iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepReplace);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_PROPERTYNAME),
|
|
pm.sPropertyName, wcslen(pm.sPropertyName)*2+2, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_CLASSID),
|
|
&pm.dClassId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_STORAGETYPEID),
|
|
&pm.iStorageTypeId, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_FLAGS),
|
|
&pm.iFlags, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_CIMTYPEID),
|
|
&pm.iCIMTypeId, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
if (bDelete)
|
|
err = JetDelete(session, tableid);
|
|
else
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertPropertyMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertPropertyMap (CSQLConnection *_pConn, DWORD &iPropID, SQL_ID dClassId, DWORD iStorageTypeId,
|
|
DWORD iCIMTypeId, LPCWSTR lpPropName, DWORD iFlags, BOOL bInsert)
|
|
{
|
|
|
|
JET_ERR err = 0;
|
|
HRESULT hr = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupPropertyMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (bInsert)
|
|
iPropID = 0;
|
|
|
|
unsigned long lLen;
|
|
PROPERTYMAP pm;
|
|
DWORD dwOldFlags = 0;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
BOOL bExists = FALSE;
|
|
JET_TABLEID tableid = pConn->GetTableID(L"PropertyMap");
|
|
|
|
hr = GetFirst_PropertyMapByClass(_pConn, dClassId, pm);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (!_wcsicmp(pm.sPropertyName, lpPropName))
|
|
{
|
|
BOOL bMatch = TRUE;
|
|
if ((iFlags & REPDRVR_FLAG_NONPROP) == (pm.iFlags & REPDRVR_FLAG_NONPROP))
|
|
{
|
|
if (iFlags & REPDRVR_FLAG_NONPROP)
|
|
{
|
|
if (iStorageTypeId != pm.iStorageTypeId)
|
|
bMatch = FALSE;
|
|
}
|
|
if (bMatch)
|
|
{
|
|
iPropID = pm.iPropertyId;
|
|
dwOldFlags = pm.iFlags;
|
|
pm.Clear();
|
|
bExists = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
hr = GetNext_PropertyMap(_pConn, pm);
|
|
if (pm.dClassId != dClassId)
|
|
break;
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
if (!bExists)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
// Now retrieve the auto-incremented ID...
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_PROPERTYID),
|
|
&iPropID, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL) ;
|
|
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_PROPERTYNAME),
|
|
lpPropName, wcslen(lpPropName)*2+2, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_CLASSID),
|
|
&dClassId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_STORAGETYPEID),
|
|
&iStorageTypeId, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_FLAGS),
|
|
&iFlags, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, PROPERTYMAP_COL_CIMTYPEID),
|
|
&iCIMTypeId, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
}
|
|
}
|
|
else if (!bInsert)
|
|
{
|
|
pm.Clear();
|
|
pm.iPropertyId = iPropID;
|
|
pm.sPropertyName = SysAllocString(lpPropName);
|
|
if (!pm.sPropertyName)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto Exit;
|
|
}
|
|
pm.dClassId = dClassId;
|
|
pm.iStorageTypeId = iStorageTypeId;
|
|
pm.iCIMTypeId = iCIMTypeId;
|
|
pm.iFlags = iFlags;
|
|
|
|
hr = UpdatePropertyMap(pConn, pm, FALSE);
|
|
pm.Clear();
|
|
}
|
|
|
|
}
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupClassKeysAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupClassKeysAccessor (CSQLConnection *_pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
if (!pConn->GetTableID(L"ClassKeys"))
|
|
{
|
|
JET_SESID session;
|
|
JET_TABLEID tableid;
|
|
JET_DBID dbid;
|
|
const LPSTR lpTbl = "ClassKeys";
|
|
BOOL bCreate = FALSE;
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
dbid = pConn->GetDBID();
|
|
|
|
JET_ERR err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
pConn->SetTableID(L"ClassKeys", tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ClassId", CLASSKEYS_COL_CLASSID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSKEYS_COL_CLASSID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"PropertyId", CLASSKEYS_COL_PROPERTYID, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSKEYS_COL_PROPERTYID, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "ClassId_idx", JET_bitIndexDisallowNull,"+ClassId\0", 10, 100);
|
|
if (err >= JET_errSuccess || err == JET_errIndexDuplicate)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "PropertyId_idx", JET_bitIndexDisallowNull ,"+PropertyId\0", 13, 100);
|
|
if (err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
}
|
|
if (err >= JET_errSuccess && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupClassKeysAccessor(_pConn);
|
|
}
|
|
}
|
|
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
Exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetClassKeysData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetClassKeysData (CSQLConnection *_pConn, JET_SESID session, JET_TABLEID tableid,
|
|
CLASSKEYS &oj)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
unsigned long lLen;
|
|
oj.iPropertyId = 0;
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSKEYS_COL_PROPERTYID),
|
|
&oj.iPropertyId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSKEYS_COL_CLASSID),
|
|
&oj.dClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassKeys
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassKeys (CSQLConnection *_pConn, SQL_ID dClassId, CLASSKEYS &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupClassKeysAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassKeys");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ClassId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dClassId, sizeof(SQL_ID), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dClassId, sizeof(SQL_ID), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
hr = GetClassKeysData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassKeysByPropertyId
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassKeysByPropertyId (CSQLConnection *_pConn,
|
|
DWORD dwPropertyId, CLASSKEYS &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupClassKeysAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassKeys");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "PropertyId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dwPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dwPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
hr = GetClassKeysData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_ClassKeys
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_ClassKeys (CSQLConnection *_pConn, CLASSKEYS &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = JET_errSuccess;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassKeys");
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetClassKeysData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdateClassKeys
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdateClassKeys(CSQLConnection *_pConn, CLASSKEYS cd, BOOL bDelete = FALSE)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
JET_ERR err = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupClassKeysAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassKeys");
|
|
|
|
err = JetSetCurrentIndex(session, tableid, "PropertyId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &cd.iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &cd.iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
while (err == JET_errSuccess)
|
|
{
|
|
CLASSKEYS ck;
|
|
ULONG lLen;
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSKEYS_COL_CLASSID),
|
|
&ck.dClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
|
|
if (ck.dClassId == cd.dClassId)
|
|
{
|
|
if (bDelete)
|
|
err = JetDelete(session, tableid);
|
|
break;
|
|
}
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertClassKeys
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertClassKeys (CSQLConnection *_pConn, SQL_ID dClassId, DWORD dwPropertyId,
|
|
BOOL bInsert)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
JET_ERR err = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupClassKeysAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CLASSKEYS oj;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassKeys");
|
|
|
|
oj.dClassId = dClassId;
|
|
oj.iPropertyId = dwPropertyId;
|
|
|
|
hr = UpdateClassKeys(pConn, oj, FALSE);
|
|
if (FAILED(hr))
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSKEYS_COL_CLASSID),
|
|
&dClassId, sizeof(__int64), 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSKEYS_COL_PROPERTYID),
|
|
&dwPropertyId, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteClassKeys
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteClassKeys (CSQLConnection *_pConn, SQL_ID dClassId, DWORD dwPropertyId = 0)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CLASSKEYS ck;
|
|
|
|
if (dwPropertyId)
|
|
hr = GetFirst_ClassKeysByPropertyId(_pConn, dwPropertyId, ck);
|
|
else
|
|
hr = GetFirst_ClassKeys(_pConn, dClassId, ck);
|
|
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
hr = UpdateClassKeys(_pConn, ck, TRUE);
|
|
|
|
hr = GetNext_ClassKeys(_pConn, ck);
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupReferencePropertiesAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupReferencePropertiesAccessor (CSQLConnection *_pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
if (!pConn->GetTableID(L"ReferenceProperties"))
|
|
{
|
|
JET_SESID session;
|
|
JET_TABLEID tableid;
|
|
JET_DBID dbid;
|
|
const LPSTR lpTbl = "ReferenceProperties";
|
|
BOOL bCreate = FALSE;
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
dbid = pConn->GetDBID();
|
|
|
|
JET_ERR err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
pConn->SetTableID(L"ReferenceProperties", tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ClassId", REFPROPS_COL_CLASSID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, REFPROPS_COL_CLASSID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"PropertyId", REFPROPS_COL_PROPERTYID, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, REFPROPS_COL_PROPERTYID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"RefClassId", REFPROPS_COL_REFCLASSID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, REFPROPS_COL_REFCLASSID, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "ClassId_idx", JET_bitIndexDisallowNull,"+ClassId\0", 10, 100);
|
|
if (err >= JET_errSuccess || err == JET_errIndexDuplicate)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "RefClassId_idx", JET_bitIndexDisallowNull,"+RefClassId\0", 13, 100);
|
|
if (err >= JET_errSuccess || err == JET_errIndexDuplicate)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "PropertyId_idx", JET_bitIndexDisallowNull ,"+PropertyId\0", 13, 100);
|
|
if (err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
}
|
|
}
|
|
if (err >= JET_errSuccess && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupReferencePropertiesAccessor(_pConn);
|
|
}
|
|
}
|
|
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
Exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetReferencePropertiesData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetReferencePropertiesData (CSQLConnection *_pConn, JET_SESID session, JET_TABLEID tableid,
|
|
REFERENCEPROPERTIES &oj)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
unsigned long lLen;
|
|
oj.iPropertyId = 0;
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, REFPROPS_COL_PROPERTYID),
|
|
&oj.iPropertyId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, REFPROPS_COL_CLASSID),
|
|
&oj.dClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, REFPROPS_COL_REFCLASSID),
|
|
&oj.dRefClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ReferenceProperties
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ReferenceProperties (CSQLConnection *_pConn, DWORD dwPropertyId,
|
|
REFERENCEPROPERTIES &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupReferencePropertiesAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ReferenceProperties");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "PropertyId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dwPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dwPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
hr = GetReferencePropertiesData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ReferencePropertiesByRef
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ReferencePropertiesByRef (CSQLConnection *_pConn, SQL_ID dRefClassId,
|
|
REFERENCEPROPERTIES &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupReferencePropertiesAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ReferenceProperties");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "RefClassId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dRefClassId, sizeof(SQL_ID), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dRefClassId, sizeof(SQL_ID), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
hr = GetReferencePropertiesData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ReferencePropertiesByClass
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ReferencePropertiesByClass (CSQLConnection *_pConn, SQL_ID dClassId,
|
|
REFERENCEPROPERTIES &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupReferencePropertiesAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ReferenceProperties");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ClassId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dClassId, sizeof(SQL_ID), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dClassId, sizeof(SQL_ID), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
hr = GetReferencePropertiesData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_ReferenceProperties
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_ReferenceProperties (CSQLConnection *_pConn, REFERENCEPROPERTIES &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = JET_errSuccess;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ReferenceProperties");
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetReferencePropertiesData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdateReferenceProperties
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdateReferenceProperties(CSQLConnection *_pConn, REFERENCEPROPERTIES cd, BOOL bDelete = FALSE,
|
|
BOOL bAllowMultiple = FALSE)
|
|
{
|
|
HRESULT hr = 0;
|
|
JET_ERR err = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupReferencePropertiesAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ReferenceProperties");
|
|
|
|
err = JetSetCurrentIndex(session, tableid, "PropertyId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &cd.iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &cd.iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
while (err == JET_errSuccess)
|
|
{
|
|
REFERENCEPROPERTIES ck;
|
|
ULONG lLen;
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, REFPROPS_COL_CLASSID),
|
|
&ck.dClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
|
|
if (ck.dClassId == cd.dClassId)
|
|
{
|
|
BOOL bFound = TRUE;
|
|
if (bAllowMultiple)
|
|
{
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, REFPROPS_COL_REFCLASSID),
|
|
&ck.dRefClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
|
|
if (ck.dRefClassId != cd.dRefClassId)
|
|
bFound = FALSE;
|
|
}
|
|
|
|
if (bFound)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepReplace);
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, REFPROPS_COL_REFCLASSID),
|
|
&ck.dRefClassId, sizeof(__int64), 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
|
|
if (bDelete)
|
|
err = JetDelete(session, tableid);
|
|
else
|
|
err = JetUpdate(session, tableid, 0, NULL, 0);
|
|
break;
|
|
}
|
|
}
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertReferenceProperties
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertReferenceProperties (CSQLConnection *_pConn, SQL_ID dClassId, DWORD dwPropertyId,
|
|
SQL_ID dRefClassId, BOOL bAllowMultiple = FALSE)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = 0;
|
|
hr = SetupReferencePropertiesAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
REFERENCEPROPERTIES oj;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ReferenceProperties");
|
|
|
|
BOOL bFound = FALSE;
|
|
hr = GetFirst_ReferenceProperties(_pConn, dClassId, oj);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (oj.iPropertyId == dwPropertyId)
|
|
{
|
|
bFound = TRUE;
|
|
if (bAllowMultiple)
|
|
{
|
|
if (dRefClassId != oj.dRefClassId)
|
|
bFound = FALSE;
|
|
}
|
|
|
|
if (bFound)
|
|
break;
|
|
}
|
|
hr = GetNext_ReferenceProperties(_pConn, oj);
|
|
}
|
|
|
|
if (!bFound)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, REFPROPS_COL_CLASSID),
|
|
&dClassId, sizeof(__int64), 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, REFPROPS_COL_REFCLASSID),
|
|
&dRefClassId, sizeof(__int64), 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, REFPROPS_COL_PROPERTYID),
|
|
&dwPropertyId, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
oj.dClassId = dClassId;
|
|
oj.iPropertyId = dwPropertyId;
|
|
oj.dRefClassId = dRefClassId;
|
|
|
|
hr = UpdateReferenceProperties(pConn, oj, FALSE, bAllowMultiple);
|
|
}
|
|
|
|
}
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteReferenceProperties
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteReferenceProperties (CSQLConnection *_pConn, DWORD dwPropertyId, SQL_ID dClassId = 0)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
REFERENCEPROPERTIES ck;
|
|
|
|
hr = GetFirst_ReferenceProperties(_pConn, dwPropertyId, ck);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
BOOL bMatch = TRUE;
|
|
|
|
if (dClassId && dClassId != ck.dClassId)
|
|
bMatch = FALSE;
|
|
|
|
if (bMatch)
|
|
hr = UpdateReferenceProperties(_pConn, ck, TRUE);
|
|
|
|
hr = GetNext_ReferenceProperties(_pConn, ck);
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteReferencePropertiesByClass
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteReferencePropertiesByClass (CSQLConnection *_pConn, SQL_ID dClassId)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
REFERENCEPROPERTIES ck;
|
|
|
|
hr = GetFirst_ReferencePropertiesByClass(_pConn, dClassId, ck);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
hr = UpdateReferenceProperties(_pConn, ck, TRUE);
|
|
|
|
hr = GetNext_ReferenceProperties(_pConn, ck);
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupClassDataAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupClassDataAccessor (CSQLConnection *_pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
JET_ERR err = JET_errSuccess;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
if (!pConn->GetTableID(L"ClassData"))
|
|
{
|
|
JET_SESID session;
|
|
JET_TABLEID tableid;
|
|
JET_DBID dbid;
|
|
const LPSTR lpTbl = "ClassData";
|
|
BOOL bCreate = FALSE;
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
dbid = pConn->GetDBID();
|
|
err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
pConn->SetTableID(L"ClassData", tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ObjectId", CLASSDATA_COL_OBJECTID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_OBJECTID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"PropertyId", CLASSDATA_COL_PROPERTYID, JET_coltypLong,
|
|
JET_bitColumnNotNULL, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_PROPERTYID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ArrayPos", CLASSDATA_COL_ARRAYPOS, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_ARRAYPOS, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"QfrPos", CLASSDATA_COL_QFRPOS, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_QFRPOS, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ClassId", CLASSDATA_COL_CLASSID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_CLASSID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"RefClassId", CLASSDATA_COL_REFCLASSID, JET_coltypCurrency,
|
|
0, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_REFCLASSID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"RefId", CLASSDATA_COL_REFID, JET_coltypCurrency,
|
|
0, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_REFID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"Flags", CLASSDATA_COL_FLAGS, JET_coltypLong,
|
|
0, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_FLAGS, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"PropertyStringValue", CLASSDATA_COL_STRINGVALUE, JET_coltypText,
|
|
0, MAX_STRING_WIDTH, &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_STRINGVALUE, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"PropertyNumericValue", CLASSDATA_COL_NUMERICVALUE, JET_coltypCurrency,
|
|
0, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_NUMERICVALUE, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"PropertyRealValue", CLASSDATA_COL_REALVALUE, JET_coltypIEEEDouble,
|
|
0, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSDATA_COL_REALVALUE, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "ObjectId_idx", JET_bitIndexDisallowNull,"+ObjectId\0", 11, 100);
|
|
if (err >= JET_errSuccess || err == JET_errIndexDuplicate)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "RefId_idx", JET_bitIndexDisallowNull ,"+RefId\0", 8, 100);
|
|
if (err >= JET_errSuccess || err == JET_errIndexDuplicate)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "PropertyId_idx", JET_bitIndexDisallowNull ,"+PropertyId\0", 13, 100);
|
|
if (err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
}
|
|
}
|
|
if (err >= JET_errSuccess && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupClassDataAccessor(_pConn);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetClassData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetClassData (CSQLConnection *_pConn, JET_SESID session, JET_TABLEID tableid,
|
|
CLASSDATA &oj, BOOL bMinimum=FALSE, CSchemaCache *pCache = NULL)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
unsigned long lLen;
|
|
wchar_t buff[1024];
|
|
oj.Clear();
|
|
oj.dRefId = 0, oj.dPropertyNumericValue = 0, oj.rPropertyRealValue = 0;
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_PROPERTYID),
|
|
&oj.iPropertyId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
if (!bMinimum)
|
|
{
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_OBJECTID),
|
|
&oj.dObjectId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_CLASSID),
|
|
&oj.dClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REFCLASSID),
|
|
&oj.dRefClassId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_QFRPOS),
|
|
&oj.iQfrPos, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
}
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_FLAGS),
|
|
&oj.iFlags, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_ARRAYPOS),
|
|
&oj.iArrayPos, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REFID),
|
|
&oj.dRefId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (!lLen)
|
|
oj.dRefId = 0;
|
|
|
|
|
|
if (!(oj.iFlags & ESE_FLAG_NULL))
|
|
{
|
|
DWORD dwPropFlags = 0;
|
|
DWORD dwStorage = 0;
|
|
if (pCache)
|
|
{
|
|
hr = pCache->GetPropertyInfo (oj.iPropertyId, NULL, NULL, &dwStorage,
|
|
NULL, &dwPropFlags);
|
|
}
|
|
if (SUCCEEDED(hr) && dwStorage != 0)
|
|
{
|
|
switch(dwStorage)
|
|
{
|
|
case WMIDB_STORAGE_REFERENCE:
|
|
case WMIDB_STORAGE_STRING:
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_STRINGVALUE),
|
|
buff, MAX_STRING_WIDTH, &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (lLen)
|
|
{
|
|
buff[lLen/2] = L'\0';
|
|
oj.sPropertyStringValue = SysAllocString(buff);
|
|
if (wcslen(buff) && !oj.sPropertyStringValue)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto exit;
|
|
}
|
|
}
|
|
break;
|
|
case WMIDB_STORAGE_NUMERIC:
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_NUMERICVALUE),
|
|
&oj.dPropertyNumericValue, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (!lLen)
|
|
oj.dPropertyNumericValue = 0;
|
|
|
|
break;
|
|
case WMIDB_STORAGE_REAL:
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REALVALUE),
|
|
&oj.rPropertyRealValue, sizeof(double), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (!lLen)
|
|
oj.rPropertyRealValue = 0;
|
|
break;
|
|
default:
|
|
hr = WBEM_E_INVALID_OPERATION;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_STRINGVALUE),
|
|
buff, MAX_STRING_WIDTH, &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (lLen)
|
|
{
|
|
buff[lLen/2] = L'\0';
|
|
oj.sPropertyStringValue = SysAllocString(buff);
|
|
if (wcslen(buff) && !oj.sPropertyStringValue)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto exit;
|
|
}
|
|
}
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_NUMERICVALUE),
|
|
&oj.dPropertyNumericValue, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (!lLen)
|
|
oj.dPropertyNumericValue = 0;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REALVALUE),
|
|
&oj.rPropertyRealValue, sizeof(double), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (!lLen)
|
|
oj.rPropertyRealValue = 0;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REFID),
|
|
&oj.dRefId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
if (!lLen)
|
|
oj.dRefId = 0;
|
|
}
|
|
}
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
exit:
|
|
|
|
return hr;
|
|
}
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassData (CSQLConnection *_pConn, SQL_ID dId, CLASSDATA &cd,
|
|
DWORD iPropertyId, BOOL bMinimum, CSchemaCache *pCache)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupClassDataAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassData");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ObjectId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
while (err == JET_errSuccess)
|
|
{
|
|
if (FAILED(GetClassData(pConn, session, tableid, cd, bMinimum, pCache)))
|
|
break;
|
|
else if (iPropertyId == -1 || cd.iPropertyId == iPropertyId)
|
|
{
|
|
hr = WBEM_S_NO_ERROR;
|
|
break;
|
|
}
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassDataByRefId
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassDataByRefId (CSQLConnection *_pConn, SQL_ID dRefId, CLASSDATA &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupClassDataAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassData");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "RefId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dRefId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dRefId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetClassData(pConn, session, tableid, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassDataByPropertyId
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassDataByPropertyId (CSQLConnection *_pConn, DWORD iPropertyId, CLASSDATA &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupClassDataAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassData");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "PropertyId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetClassData(pConn, session, tableid, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_ClassData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_ClassData (CSQLConnection *_pConn, CLASSDATA &cd, DWORD iPropertyId, BOOL bMinimum,
|
|
CSchemaCache *pCache)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
cd.Clear();
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassData");
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetClassData(pConn, session, tableid, cd, bMinimum, pCache);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdateClassData_Internal
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdateClassData_Internal(CSQLConnection *_pConn, CLASSDATA cd, BOOL bDelete = FALSE)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = 0;
|
|
|
|
hr = SetupClassDataAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
unsigned long lLen;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassData");
|
|
|
|
err = JetSetCurrentIndex(session, tableid, "ObjectId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &cd.dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &cd.dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
|
|
while (err == JET_errSuccess)
|
|
{
|
|
CLASSDATA cd2;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_OBJECTID),
|
|
&cd2.dObjectId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_ARRAYPOS),
|
|
&cd2.iArrayPos, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_QFRPOS),
|
|
&cd2.iQfrPos, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_PROPERTYID),
|
|
&cd2.iPropertyId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
|
|
if (cd.dObjectId == cd2.dObjectId &&
|
|
cd.iPropertyId == cd2.iPropertyId &&
|
|
cd.iQfrPos == cd2.iQfrPos &&
|
|
cd.iArrayPos == cd2.iArrayPos)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepReplace);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_OBJECTID),
|
|
&cd.dObjectId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_CLASSID),
|
|
&cd.dClassId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REFID),
|
|
&cd.dRefId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_NUMERICVALUE),
|
|
&cd.dPropertyNumericValue, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REFCLASSID),
|
|
&cd.dRefClassId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_ARRAYPOS),
|
|
&cd.iArrayPos, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_QFRPOS),
|
|
&cd.iQfrPos, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_FLAGS),
|
|
&cd.iFlags, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_PROPERTYID),
|
|
&cd.iPropertyId, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REALVALUE),
|
|
&cd.rPropertyRealValue, sizeof(double), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
if (cd.sPropertyStringValue)
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_STRINGVALUE),
|
|
cd.sPropertyStringValue, wcslen(cd.sPropertyStringValue)*2+2, 0, NULL);
|
|
else
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_STRINGVALUE),
|
|
NULL, 0, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
|
|
if (bDelete)
|
|
err = JetDelete(session, tableid);
|
|
else
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertClassData_Internal
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertClassData_Internal (CSQLConnection *_pConn, SQL_ID dObjectId, DWORD iPropID, DWORD iArrayPos, DWORD iQfrPos,
|
|
SQL_ID dClassId, LPCWSTR lpStringValue, SQL_ID dNumericValue, double fRealValue,
|
|
DWORD iFlags, SQL_ID dRefId, SQL_ID dRefClassId, BOOL bIsNull)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
JET_ERR err = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupClassDataAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassData");
|
|
|
|
CLASSDATA cd;
|
|
|
|
cd.dObjectId = dObjectId;
|
|
cd.dClassId = dClassId;
|
|
cd.iArrayPos = iArrayPos;
|
|
cd.iQfrPos = iQfrPos;
|
|
cd.iPropertyId = iPropID;
|
|
cd.iFlags = iFlags;
|
|
if (bIsNull)
|
|
cd.iFlags |= ESE_FLAG_NULL;
|
|
if (!bIsNull)
|
|
{
|
|
cd.dRefId = dRefId;
|
|
cd.dRefClassId = dRefClassId;
|
|
cd.rPropertyRealValue = fRealValue;
|
|
cd.dPropertyNumericValue = dNumericValue;
|
|
if (lpStringValue)
|
|
{
|
|
LPWSTR lpVal = StripQuotes2((LPWSTR)lpStringValue);
|
|
CDeleteMe <wchar_t> d (lpVal);
|
|
cd.sPropertyStringValue = SysAllocString(lpVal);
|
|
if (!cd.sPropertyStringValue)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
cd.sPropertyStringValue = NULL;
|
|
}
|
|
else
|
|
{
|
|
cd.dRefId =0;
|
|
cd.dRefClassId = 0;
|
|
cd.rPropertyRealValue = 0;
|
|
cd.dPropertyNumericValue = 0;
|
|
cd.sPropertyStringValue = NULL;
|
|
}
|
|
|
|
hr = UpdateClassData_Internal(pConn, cd, FALSE);
|
|
if (FAILED(hr))
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_OBJECTID),
|
|
&dObjectId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_CLASSID),
|
|
&dClassId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
// NOTE: This can't be null, because we have an index on it...
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REFID),
|
|
&dRefId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
if (!bIsNull)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_NUMERICVALUE),
|
|
&dNumericValue, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REFCLASSID),
|
|
&dRefClassId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REALVALUE),
|
|
&fRealValue, sizeof(double), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
if (cd.sPropertyStringValue)
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_STRINGVALUE),
|
|
cd.sPropertyStringValue, wcslen(cd.sPropertyStringValue)*2+2, 0, NULL);
|
|
}
|
|
else
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_NUMERICVALUE),
|
|
NULL, 0, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REFCLASSID),
|
|
NULL, 0, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_REALVALUE),
|
|
NULL, 0, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_STRINGVALUE),
|
|
NULL, 0, 0, NULL);
|
|
}
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_ARRAYPOS),
|
|
&iArrayPos, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_QFRPOS),
|
|
&iQfrPos, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_FLAGS),
|
|
&cd.iFlags, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSDATA_COL_PROPERTYID),
|
|
&iPropID, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
cd.Clear();
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupClassImagesAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupClassImagesAccessor (CSQLConnection *_pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
if (!pConn->GetTableID(L"ClassImages"))
|
|
{
|
|
JET_SESID session;
|
|
JET_TABLEID tableid;
|
|
JET_DBID dbid;
|
|
BOOL bCreate = FALSE;
|
|
const LPSTR lpTbl = "ClassImages";
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
dbid = pConn->GetDBID();
|
|
err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
pConn->SetTableID(L"ClassImages", tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ObjectId", CLASSIMAGES_COL_OBJECTID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSIMAGES_COL_OBJECTID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"PropertyId", CLASSIMAGES_COL_PROPERTYID, JET_coltypLong,
|
|
JET_bitColumnNotNULL, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSIMAGES_COL_PROPERTYID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ArrayPos", CLASSIMAGES_COL_ARRAYPOS, JET_coltypLong,
|
|
JET_bitColumnNotNULL, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSIMAGES_COL_ARRAYPOS, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"PropertyImageValue", CLASSIMAGES_COL_IMAGEVALUE, JET_coltypLongBinary,
|
|
0, 0, &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CLASSIMAGES_COL_IMAGEVALUE, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "ObjectId_idx", JET_bitIndexDisallowNull,"+ObjectId\0", 11, 100);
|
|
if (err >= JET_errSuccess ||err == JET_errIndexDuplicate)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "PropertyId_idx", JET_bitIndexDisallowNull ,"+PropertyId\0", 13, 100);
|
|
if (err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
}
|
|
if (err >= JET_errSuccess && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupClassImagesAccessor(_pConn);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetClassImagesData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetClassImagesData (CSQLConnection *_pConn, JET_SESID session, JET_TABLEID tableid,
|
|
CLASSIMAGES &oj)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
unsigned long lLen;
|
|
BYTE buff[128];
|
|
oj.Clear();
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_OBJECTID),
|
|
&oj.dObjectId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_PROPERTYID),
|
|
&oj.iPropertyId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_ARRAYPOS),
|
|
&oj.iArrayPos, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_IMAGEVALUE),
|
|
buff, 128, &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
if(lLen > 0)
|
|
{
|
|
oj.pBuffer = new BYTE[lLen];
|
|
if (oj.pBuffer)
|
|
{
|
|
oj.dwBufferLen = lLen;
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_IMAGEVALUE),
|
|
oj.pBuffer, oj.dwBufferLen, &lLen, JET_bitRetrieveCopy, NULL);
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassImages
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassImages (CSQLConnection *_pConn, SQL_ID dId, CLASSIMAGES &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupClassImagesAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassImages");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ObjectId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetClassImagesData(pConn, session, tableid, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ClassImagesByPropertyId
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ClassImagesByPropertyId (CSQLConnection *_pConn, DWORD iPropertyId, CLASSIMAGES &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupClassImagesAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassImages");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "PropertyId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetClassImagesData(pConn, session, tableid, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_ClassImages
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_ClassImages (CSQLConnection *_pConn, CLASSIMAGES &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
cd.Clear();
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassImages");
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetClassImagesData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdateClassImages
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdateClassImages (CSQLConnection *_pConn, CLASSIMAGES cd, BOOL bDelete = FALSE)
|
|
{
|
|
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = 0;
|
|
hr = SetupClassImagesAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
unsigned long lLen;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassImages");
|
|
|
|
err = JetSetCurrentIndex(session, tableid, "ObjectId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &cd.dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &cd.dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
|
|
while (err == JET_errSuccess)
|
|
{
|
|
CLASSIMAGES cd2;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_OBJECTID),
|
|
&cd2.dObjectId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_ARRAYPOS),
|
|
&cd2.iArrayPos, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_PROPERTYID),
|
|
&cd2.iPropertyId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
|
|
if (cd.dObjectId == cd2.dObjectId &&
|
|
cd.iPropertyId == cd2.iPropertyId &&
|
|
cd.iArrayPos == cd2.iArrayPos)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepReplace);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_OBJECTID),
|
|
&cd.dObjectId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_ARRAYPOS),
|
|
&cd.iArrayPos, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_PROPERTYID),
|
|
&cd.iPropertyId, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_IMAGEVALUE),
|
|
cd.pBuffer, cd.dwBufferLen, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
|
|
if (bDelete)
|
|
err = JetDelete(session, tableid);
|
|
else
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertClassImages
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertClassImages (CSQLConnection *_pConn, SQL_ID dObjectId, DWORD iPropID, DWORD iArrayPos,
|
|
BYTE *pStream = NULL, DWORD dwLength = 0)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
JET_ERR err = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupClassImagesAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ClassImages");
|
|
|
|
CLASSIMAGES cd;
|
|
|
|
cd.dObjectId = dObjectId;
|
|
cd.iArrayPos = iArrayPos;
|
|
cd.iPropertyId = iPropID;
|
|
cd.pBuffer = pStream;
|
|
cd.dwBufferLen = dwLength;
|
|
|
|
hr = UpdateClassImages(pConn, cd, FALSE);
|
|
if (FAILED(hr))
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_OBJECTID),
|
|
&dObjectId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_ARRAYPOS),
|
|
&iArrayPos, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_PROPERTYID),
|
|
&iPropID, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CLASSIMAGES_COL_IMAGEVALUE),
|
|
pStream, dwLength, 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
|
|
}
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupIndexDataAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupIndexDataAccessor (CSQLConnection *_pConn, DWORD dwStorage, DWORD &dwPos, LPWSTR * lpTableName)
|
|
{
|
|
HRESULT hr = 0;
|
|
char szTable [30];
|
|
wchar_t wTable[30];
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_COLTYP coltype;
|
|
JET_TABLEID tableid;
|
|
JET_ERR err = JET_errSuccess;
|
|
switch(dwStorage)
|
|
{
|
|
case WMIDB_STORAGE_STRING:
|
|
dwPos = SQL_POS_INDEXSTRING;
|
|
tableid = pConn->GetTableID(L"IndexStringData");
|
|
strcpy(szTable, "IndexStringData");
|
|
coltype = JET_coltypText;
|
|
break;
|
|
case WMIDB_STORAGE_REFERENCE:
|
|
dwPos = SQL_POS_INDEXREF;
|
|
strcpy(szTable, "IndexRefData");
|
|
tableid = pConn->GetTableID(L"IndexRefData");
|
|
coltype = JET_coltypCurrency;
|
|
break;
|
|
case WMIDB_STORAGE_NUMERIC:
|
|
dwPos = SQL_POS_INDEXNUMERIC;
|
|
strcpy(szTable, "IndexNumericData");
|
|
tableid = pConn->GetTableID(L"IndexNumericData");
|
|
coltype = JET_coltypCurrency;
|
|
break;
|
|
case WMIDB_STORAGE_REAL:
|
|
dwPos = SQL_POS_INDEXREAL;
|
|
coltype = JET_coltypIEEEDouble;
|
|
strcpy(szTable, "IndexRealData");
|
|
tableid = pConn->GetTableID(L"IndexRealData");
|
|
break;
|
|
default:
|
|
dwPos = 0;
|
|
break;
|
|
}
|
|
|
|
if (dwPos != 0)
|
|
{
|
|
swprintf(wTable, L"%S", szTable);
|
|
|
|
if (!tableid)
|
|
{
|
|
JET_SESID session;
|
|
JET_DBID dbid;
|
|
BOOL bCreate = FALSE;
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
dbid = pConn->GetDBID();
|
|
err = JetOpenTable (session, dbid, szTable, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, szTable, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
|
|
}
|
|
else
|
|
pConn->SetTableID(wTable, tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, szTable, L"ObjectId", INDEXTBL_COL_OBJECTID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, INDEXTBL_COL_OBJECTID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, szTable, L"PropertyId", INDEXTBL_COL_PROPERTYID, JET_coltypLong,
|
|
JET_bitColumnNotNULL, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, INDEXTBL_COL_PROPERTYID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, szTable, L"ArrayPos", INDEXTBL_COL_ARRAYPOS, JET_coltypLong,
|
|
JET_bitColumnNotNULL, sizeof(DWORD), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, INDEXTBL_COL_ARRAYPOS, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, szTable, L"IndexValue", INDEXTBL_COL_INDEXVALUE, coltype,
|
|
0, 2, &colid);
|
|
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, INDEXTBL_COL_INDEXVALUE, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "ObjectId_idx", JET_bitIndexDisallowNull,"+ObjectId\0", 11, 100);
|
|
if (err >= JET_errSuccess || JET_errIndexDuplicate == err)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "PropertyId_idx", JET_bitIndexDisallowNull ,"+PropertyId\0", 13, 100);
|
|
if (err >= JET_errSuccess || JET_errIndexDuplicate == err)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "IndexValue_idx", JET_bitIndexDisallowNull ,"+IndexValue\0", 13, 80);
|
|
if (err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
}
|
|
}
|
|
if (err >= JET_errSuccess && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupIndexDataAccessor(_pConn,dwStorage, dwPos, lpTableName);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (lpTableName)
|
|
{
|
|
*lpTableName = new wchar_t [wcslen(wTable) + 1];
|
|
if (!*lpTableName)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto Exit;
|
|
}
|
|
wcscpy(*lpTableName, wTable);
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetIndexData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetIndexData (CSQLConnection *_pConn, JET_SESID session, JET_TABLEID tableid,
|
|
DWORD dwPos, INDEXDATA &is)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
BYTE buff[512];
|
|
long lInLen = 0;
|
|
unsigned long lLen;
|
|
is.Clear();
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_OBJECTID),
|
|
&is.dObjectId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_PROPERTYID),
|
|
&is.iPropertyId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_ARRAYPOS),
|
|
&is.iArrayPos, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
switch(dwPos)
|
|
{
|
|
case SQL_POS_INDEXNUMERIC:
|
|
case SQL_POS_INDEXREF:
|
|
lInLen = sizeof(SQL_ID);
|
|
break;
|
|
case SQL_POS_INDEXSTRING:
|
|
lInLen = MAX_STRING_WIDTH;
|
|
break;
|
|
case SQL_POS_INDEXREAL:
|
|
lInLen = sizeof(double);
|
|
break;
|
|
}
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_INDEXVALUE),
|
|
buff, MAX_STRING_WIDTH, &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
if (lLen > 0)
|
|
{
|
|
switch(dwPos)
|
|
{
|
|
case SQL_POS_INDEXNUMERIC:
|
|
case SQL_POS_INDEXREF:
|
|
is.dValue = *((SQL_ID *)buff);
|
|
break;
|
|
case SQL_POS_INDEXSTRING:
|
|
is.sValue = SysAllocString((LPWSTR)buff);
|
|
if (!is.sValue)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto exit;
|
|
}
|
|
break;
|
|
case SQL_POS_INDEXREAL:
|
|
is.rValue = *((double *)buff);
|
|
break;
|
|
default:
|
|
break; // don't set anything - the caller doesn't want this data.
|
|
}
|
|
}
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_IndexData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_IndexData (CSQLConnection *_pConn, SQL_ID dObjectId, INDEXDATA &cd,
|
|
JET_TABLEID &tableid, DWORD dwPos)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ObjectId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dObjectId, sizeof(SQL_ID), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dObjectId, sizeof(SQL_ID), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_IndexDataByProperty
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_IndexDataByProperty (CSQLConnection *_pConn, SQL_ID PropertyId, INDEXDATA &cd,
|
|
JET_TABLEID tableid, DWORD dwPos)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "PropertyId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &PropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &PropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// OpenEnum_IndexDataNumeric
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT OpenEnum_IndexDataNumeric (CSQLConnection *_pConn, SQL_ID dStartAt, INDEXDATA &cd,
|
|
JET_TABLEID &tableid, DWORD &dwPos)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
LPWSTR lpTableName;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this value and bind the data.
|
|
|
|
hr = SetupIndexDataAccessor(pConn, WMIDB_STORAGE_NUMERIC, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CDeleteMe <wchar_t> d(lpTableName);
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
tableid = pConn->GetTableID(lpTableName);
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "IndexValue_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dStartAt, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekGE );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_IndexDataNumeric
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_IndexDataNumeric (CSQLConnection *_pConn, SQL_ID dNumericValue, INDEXDATA &cd,
|
|
JET_TABLEID &tableid, DWORD &dwPos)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
LPWSTR lpTableName;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this value and bind the data.
|
|
|
|
hr = SetupIndexDataAccessor(pConn, WMIDB_STORAGE_NUMERIC, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CDeleteMe <wchar_t> d(lpTableName);
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
tableid = pConn->GetTableID(lpTableName);
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "IndexValue_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dNumericValue, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dNumericValue, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// OpenEnum_IndexDataString
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT OpenEnum_IndexDataString (CSQLConnection *_pConn, LPWSTR lpStartAt, INDEXDATA &cd,
|
|
JET_TABLEID &tableid, DWORD &dwPos)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
LPWSTR lpTableName;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this value and bind the data.
|
|
|
|
hr = SetupIndexDataAccessor(pConn, WMIDB_STORAGE_STRING, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CDeleteMe <wchar_t> d(lpTableName);
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
tableid = pConn->GetTableID(lpTableName);
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "IndexValue_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, lpStartAt, wcslen(lpStartAt)*2+2, JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekGE );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_IndexDataString
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_IndexDataString (CSQLConnection *_pConn, LPWSTR lpStringValue, INDEXDATA &cd,
|
|
JET_TABLEID &tableid, DWORD &dwPos)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
LPWSTR lpTableName;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this value and bind the data.
|
|
|
|
hr = SetupIndexDataAccessor(pConn, WMIDB_STORAGE_STRING, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CDeleteMe <wchar_t> d(lpTableName);
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
tableid = pConn->GetTableID(lpTableName);
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "IndexValue_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, lpStringValue, wcslen(lpStringValue)*2+2, JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, lpStringValue, wcslen(lpStringValue)*2+2, JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (err == JET_errSuccess)
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// OpenEnum_IndexDataReal
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT OpenEnum_IndexDataReal (CSQLConnection *_pConn, double dStartAt, INDEXDATA &cd,
|
|
JET_TABLEID &tableid, DWORD &dwPos)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
LPWSTR lpTableName;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this value and bind the data.
|
|
|
|
hr = SetupIndexDataAccessor(pConn, WMIDB_STORAGE_REAL, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CDeleteMe <wchar_t> d(lpTableName);
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
tableid = pConn->GetTableID(lpTableName);
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "IndexValue_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dStartAt, sizeof(double), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekGE );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_IndexDataReal
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_IndexDataReal (CSQLConnection *_pConn, double dValue, INDEXDATA &cd,
|
|
JET_TABLEID &tableid, DWORD &dwPos)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
LPWSTR lpTableName;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
// Locate the first row for this value and bind the data.
|
|
|
|
hr = SetupIndexDataAccessor(pConn, WMIDB_STORAGE_REAL, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CDeleteMe <wchar_t> d(lpTableName);
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
tableid = pConn->GetTableID(lpTableName);
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "IndexValue_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dValue, sizeof(double), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dValue, sizeof(double), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// OpenEnum_IndexDataRef
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT OpenEnum_IndexDataRef (CSQLConnection *_pConn, SQL_ID dStartAt, INDEXDATA &cd,
|
|
JET_TABLEID &tableid, DWORD &dwPos)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
LPWSTR lpTableName;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this value and bind the data.
|
|
|
|
hr = SetupIndexDataAccessor(pConn, WMIDB_STORAGE_REFERENCE, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
CDeleteMe <wchar_t> d(lpTableName);
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
tableid = pConn->GetTableID(lpTableName);
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "IndexValue_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dStartAt, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekGE );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_IndexDataRef
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_IndexDataRef (CSQLConnection *_pConn, SQL_ID dValue, INDEXDATA &cd,
|
|
JET_TABLEID &tableid, DWORD &dwPos)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
LPWSTR lpTableName;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this value and bind the data.
|
|
|
|
hr = SetupIndexDataAccessor(pConn, WMIDB_STORAGE_REFERENCE, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
CDeleteMe <wchar_t> d(lpTableName);
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
tableid = pConn->GetTableID(lpTableName);
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "IndexValue_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dValue, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dValue, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (err == JET_errSuccess)
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (err != JET_errSuccess)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_IndexData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_IndexData (CSQLConnection *_pConn, JET_TABLEID tableid, DWORD dwPos, INDEXDATA &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
cd.Clear();
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetIndexData(pConn, session, tableid, dwPos, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdateIndexData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdateIndexData (CSQLConnection *_pConn, INDEXDATA is, LPWSTR lpTableName, DWORD dwStorage, BOOL bDelete = FALSE)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(lpTableName);
|
|
unsigned long lLen;
|
|
|
|
err = JetSetCurrentIndex(session, tableid, "ObjectId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &is.dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &is.dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
|
|
while (err == JET_errSuccess)
|
|
{
|
|
INDEXDATA is2;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_ARRAYPOS),
|
|
&is2.iArrayPos, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_PROPERTYID),
|
|
&is2.iPropertyId, sizeof(DWORD), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto Exit;
|
|
|
|
if (is.iPropertyId == is2.iPropertyId &&
|
|
is.iArrayPos == is2.iArrayPos)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepReplace);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
switch(dwStorage)
|
|
{
|
|
case WMIDB_STORAGE_STRING:
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_INDEXVALUE),
|
|
is.sValue, wcslen(is.sValue)*2+2, 0, NULL);
|
|
break;
|
|
case WMIDB_STORAGE_NUMERIC:
|
|
case WMIDB_STORAGE_REFERENCE:
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_INDEXVALUE),
|
|
&is.dValue, sizeof(SQL_ID), 0, NULL);
|
|
break;
|
|
case WMIDB_STORAGE_REAL:
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_INDEXVALUE),
|
|
&is.rValue, sizeof(SQL_ID), 0, NULL);
|
|
break;
|
|
}
|
|
if (bDelete)
|
|
err = JetDelete(session, tableid);
|
|
else
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertIndexData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertIndexData (CSQLConnection *_pConn, SQL_ID dObjectId, DWORD iPropID, DWORD iArrayPos,
|
|
LPWSTR lpValue, SQL_ID dValue, double rValue, DWORD dwStorage)
|
|
{
|
|
HRESULT hr = 0;
|
|
DWORD dwPos = 0;
|
|
LPWSTR lpTableName = NULL;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = 0;
|
|
|
|
hr = SetupIndexDataAccessor(pConn, dwStorage, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (dwStorage == WMIDB_STORAGE_IMAGE || !lpTableName)
|
|
return 0;
|
|
|
|
CDeleteMe <wchar_t> d (lpTableName);
|
|
|
|
INDEXDATA is;
|
|
|
|
is.dObjectId = dObjectId;
|
|
is.iPropertyId = iPropID;
|
|
is.iArrayPos = iArrayPos;
|
|
is.sValue = SysAllocString(lpValue);
|
|
if (lpValue && !is.sValue)
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
goto Exit;
|
|
}
|
|
is.dValue = dValue;
|
|
is.rValue = rValue;
|
|
|
|
if (FAILED(UpdateIndexData(pConn, is, lpTableName, dwStorage)))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(lpTableName);
|
|
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_OBJECTID),
|
|
&dObjectId, sizeof(__int64), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_ARRAYPOS),
|
|
&iArrayPos, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_PROPERTYID),
|
|
&iPropID, sizeof(DWORD), 0, NULL);
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
switch(dwStorage)
|
|
{
|
|
case WMIDB_STORAGE_STRING:
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_INDEXVALUE),
|
|
lpValue, wcslen(lpValue)*2+2, 0, NULL);
|
|
break;
|
|
case WMIDB_STORAGE_NUMERIC:
|
|
case WMIDB_STORAGE_REFERENCE:
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_INDEXVALUE),
|
|
&dValue, sizeof(SQL_ID), 0, NULL);
|
|
break;
|
|
case WMIDB_STORAGE_REAL:
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, INDEXTBL_COL_INDEXVALUE),
|
|
&rValue, sizeof(double), 0, NULL);
|
|
break;
|
|
}
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
|
|
}
|
|
}
|
|
is.Clear();
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupContainerObjsAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupContainerObjsAccessor (CSQLConnection *_pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = JET_errSuccess;
|
|
if (!pConn->GetTableID(L"ContainerObjs"))
|
|
{
|
|
JET_SESID session;
|
|
JET_TABLEID tableid;
|
|
JET_DBID dbid;
|
|
const LPSTR lpTbl = "ContainerObjs";
|
|
BOOL bCreate = FALSE;
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
dbid = pConn->GetDBID();
|
|
err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
pConn->SetTableID(L"ContainerObjs", tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ContainerId", CONTAINEROBJS_COL_CONTAINERID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CONTAINEROBJS_COL_CONTAINERID, colid);
|
|
else
|
|
goto Exit;
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ContaineeId", CONTAINEROBJS_COL_CONTAINEEID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, CONTAINEROBJS_COL_CONTAINEEID, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "ContainerObjs_PK", JET_bitIndexDisallowNull,"+ContainerId\0", 14, 100);
|
|
if (err >= JET_errSuccess || JET_errIndexDuplicate == err)
|
|
{
|
|
err = JetCreateIndex(session, tableid, "Containee_idx", JET_bitIndexDisallowNull ,"+ContaineeId\0", 14, 100);
|
|
if (err == JET_errIndexDuplicate)
|
|
err = JET_errSuccess;
|
|
}
|
|
|
|
if (err >= JET_errSuccess && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupContainerObjsAccessor(_pConn);
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetContainerObjsData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetContainerObjsData (CSQLConnection *_pConn, JET_SESID session, JET_TABLEID tableid,
|
|
CONTAINEROBJ &co)
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
unsigned long lLen;
|
|
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CONTAINEROBJS_COL_CONTAINERID),
|
|
&co.dContainerId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, CONTAINEROBJS_COL_CONTAINEEID),
|
|
&co.dContaineeId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
if (JET_errSuccess > err)
|
|
goto exit;
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
exit:
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ContainerObjs
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ContainerObjs (CSQLConnection *_pConn, SQL_ID dContainerId, CONTAINEROBJ &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupContainerObjsAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ContainerObjs");
|
|
|
|
// Use the default index
|
|
// Grab the first row,
|
|
// and stuff it into the OBJECTMAP object.
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "ContainerObjs_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dContainerId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dContainerId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
hr = GetContainerObjsData(pConn, session, tableid, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetFirst_ContainerObjsByContainee
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetFirst_ContainerObjsByContainee (CSQLConnection *_pConn, SQL_ID dContaineeId, CONTAINEROBJ &cd)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupContainerObjsAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ContainerObjs");
|
|
|
|
// Use the default index
|
|
// Grab the first row,
|
|
// and stuff it into the OBJECTMAP object.
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "Containee_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dContaineeId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &dContaineeId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
if (err == JET_errSuccess)
|
|
hr = GetContainerObjsData(pConn, session, tableid, cd);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_ContainerObjs
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_ContainerObjs (CSQLConnection *_pConn, CONTAINEROBJ &cd)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
cd.Clear();
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ContainerObjs");
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
hr = GetContainerObjsData(pConn, session, tableid, cd);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// UpdateContainerObjs
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT UpdateContainerObjs (CSQLConnection *_pConn, CONTAINEROBJ co, BOOL bDelete = FALSE)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
if (!bDelete)
|
|
return 0;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ContainerObjs");
|
|
|
|
err = JetSetCurrentIndex(session, tableid, "ContainerObjs_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &co.dContainerId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &co.dContainerId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeInclusive|JET_bitRangeUpperLimit);
|
|
|
|
while (err == JET_errSuccess)
|
|
{
|
|
CONTAINEROBJ co2;
|
|
hr = GetContainerObjsData(pConn, session, tableid, co2);
|
|
if (co.dContainerId == co2.dContainerId &&
|
|
co.dContaineeId == co2.dContaineeId)
|
|
{
|
|
err = JetDelete(session, tableid);
|
|
break;
|
|
}
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertContainerObjs
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertContainerObjs(CSQLConnection *pConn2, SQL_ID dContainerId, SQL_ID dContaineeId)
|
|
{
|
|
|
|
HRESULT hr = 0;
|
|
JET_ERR err = 0;
|
|
CESEConnection *pConn = (CESEConnection *)pConn2;
|
|
hr = SetupContainerObjsAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"ContainerObjs");
|
|
|
|
BOOL bFound = FALSE;
|
|
CONTAINEROBJ co;
|
|
hr = GetFirst_ContainerObjs(pConn2, dContainerId, co);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (co.dContainerId == dContainerId &&
|
|
co.dContaineeId == dContaineeId)
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
|
|
hr = GetNext_ContainerObjs(pConn2, co);
|
|
}
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
if (!bFound)
|
|
{
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CONTAINEROBJS_COL_CONTAINERID),
|
|
&dContainerId, sizeof(__int64), 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, CONTAINEROBJS_COL_CONTAINEEID),
|
|
&dContaineeId, sizeof(__int64), 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// SetupAutoDeleteAccessor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT SetupAutoDeleteAccessor(CSQLConnection *_pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = JET_errSuccess;
|
|
if (!pConn->GetTableID(L"AutoDelete"))
|
|
{
|
|
JET_SESID session;
|
|
JET_TABLEID tableid;
|
|
JET_DBID dbid;
|
|
const LPSTR lpTbl = "AutoDelete";
|
|
BOOL bCreate = FALSE;
|
|
|
|
// Get the session and table ID
|
|
// and create columns as needed.
|
|
|
|
session = pConn->GetSessionID();
|
|
dbid = pConn->GetDBID();
|
|
err = JetOpenTable (session, dbid, lpTbl, NULL, 0, JET_bitTableUpdatable, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
CSQLExecute::GetWMIError(err);
|
|
bCreate = TRUE;
|
|
err = JetCreateTable(session, dbid, lpTbl, 10, 80, &tableid);
|
|
if (err < JET_errSuccess)
|
|
{
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
goto Exit;
|
|
}
|
|
}
|
|
else
|
|
pConn->SetTableID(L"AutoDelete", tableid);
|
|
|
|
JET_COLUMNID colid;
|
|
|
|
hr = AddColumnToTable(pConn, tableid, lpTbl, L"ObjectId", CONTAINEROBJS_COL_CONTAINERID, JET_coltypCurrency,
|
|
JET_bitColumnNotNULL, sizeof(SQL_ID), &colid);
|
|
if (SUCCEEDED(hr))
|
|
pConn->SetColumnID(tableid, AUTODELETE_COL_OBJECTID, colid);
|
|
else
|
|
goto Exit;
|
|
|
|
err = JetCreateIndex(session, tableid, "AutoDelete_PK", JET_bitIndexPrimary | JET_bitIndexUnique,"+ObjectId\0", 11, 100);
|
|
if (err >= JET_errSuccess || JET_errIndexHasPrimary == err)
|
|
err = JET_errSuccess;
|
|
|
|
if (err >= JET_errSuccess && bCreate)
|
|
{
|
|
err = JetCloseTable(session, tableid);
|
|
if (err >= JET_errSuccess)
|
|
{
|
|
hr = SetupAutoDeleteAccessor(_pConn);
|
|
}
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// OpenEnum_AutoDelete
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT OpenEnum_AutoDelete (CSQLConnection *_pConn, AUTODELETE &ad)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = SetupAutoDeleteAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"AutoDelete");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "AutoDelete_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMove(session, tableid, JET_MoveFirst, 0);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
ULONG lLen;
|
|
err = JetRetrieveColumn(session, tableid, pConn->GetColumnID(tableid, AUTODELETE_COL_OBJECTID),
|
|
&ad.dObjectId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL);
|
|
}
|
|
}
|
|
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetNext_AutoDelete
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetNext_AutoDelete(CSQLConnection *_pConn, AUTODELETE &ad)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
JET_ERR err = JET_errSuccess;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"AutoDelete");
|
|
|
|
err = JetMove(session, tableid, JET_MoveNext, 0);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
ULONG lLen;
|
|
hr = CSQLExecute::GetWMIError(JetRetrieveColumn(session, tableid,
|
|
pConn->GetColumnID(tableid, AUTODELETE_COL_OBJECTID),
|
|
&ad.dObjectId, sizeof(SQL_ID), &lLen, JET_bitRetrieveCopy, NULL));
|
|
}
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// InsertAutoDelete
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT InsertAutoDelete(CSQLConnection *_pConn, SQL_ID dObjectId)
|
|
{
|
|
HRESULT hr = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
JET_ERR err = 0;
|
|
hr = SetupAutoDeleteAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"AutoDelete");
|
|
|
|
hr = DeleteAutoDelete(pConn, dObjectId);
|
|
|
|
err = JetPrepareUpdate(session, tableid, JET_prepInsert);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetColumn(session, tableid, pConn->GetColumnID(tableid, AUTODELETE_COL_OBJECTID),
|
|
&dObjectId, sizeof(__int64), 0, NULL );
|
|
if (err < JET_errSuccess)
|
|
goto Exit;
|
|
|
|
err = JetUpdate(session, tableid, NULL, 0, NULL );
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
if (err)
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteAutoDelete
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteAutoDelete(CSQLConnection *_pConn, SQL_ID dObjectId)
|
|
{
|
|
HRESULT hr = WBEM_E_NOT_FOUND;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Locate the first row for this ObjectID and bind the data.
|
|
|
|
hr = SetupAutoDeleteAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"AutoDelete");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "AutoDelete_PK");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSetIndexRange(session, tableid, JET_bitRangeRemove);
|
|
err = JetMakeKey(session, tableid, &dObjectId, sizeof(__int64), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetDelete(session, tableid);
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CleanAutoDeletes
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CleanAutoDeletes(CSQLConnection *pConn)
|
|
{
|
|
HRESULT hr;
|
|
AUTODELETE ad;
|
|
SQLIDs ids;
|
|
|
|
// These are objects created with the AUTODELETE handle.
|
|
// If we have any left, we must have crashed before
|
|
// the handles could be tidied up.
|
|
|
|
hr = OpenEnum_AutoDelete(pConn, ad);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
ids.push_back(ad.dObjectId);
|
|
|
|
hr = GetNext_AutoDelete(pConn, ad);
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
for (int i = 0; i < ids.size(); i++)
|
|
{
|
|
hr = DeleteObjectMap(pConn, ids.at(i));
|
|
if (FAILED(hr))
|
|
break;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// Delete functions
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteIndexDataByObjectId
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteIndexDataByObjectId (CSQLConnection *_pConn, DWORD dwStorage, SQL_ID dObjectId)
|
|
{
|
|
HRESULT hr = 0;
|
|
LPWSTR lpTableName = NULL;
|
|
DWORD dwPos = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
hr = SetupIndexDataAccessor(pConn, dwStorage, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CDeleteMe <wchar_t> d (lpTableName);
|
|
|
|
if (!lpTableName || dwStorage == WMIDB_STORAGE_IMAGE)
|
|
return 0;
|
|
|
|
INDEXDATA is;
|
|
JET_TABLEID tableid = pConn->GetTableID(lpTableName);
|
|
|
|
hr = GetFirst_IndexData(pConn, dObjectId, is, tableid, dwPos);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
hr = UpdateIndexData(pConn, is, lpTableName, dwStorage, TRUE);
|
|
if (FAILED(hr))
|
|
{
|
|
is.Clear();
|
|
break;
|
|
}
|
|
|
|
hr = GetNext_IndexData(pConn, tableid, dwPos, is);
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
{
|
|
hr = WBEM_S_NO_ERROR;
|
|
break;
|
|
}
|
|
if (is.dObjectId != dObjectId)
|
|
break;
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeletePropertyMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeletePropertyMap (CSQLConnection *_pConn, DWORD iPropertyId)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
PROPERTYMAP pm;
|
|
hr = GetFirst_PropertyMap(pConn, iPropertyId, pm);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = DeleteReferenceProperties(_pConn, iPropertyId);
|
|
if (SUCCEEDED(hr))
|
|
hr = UpdatePropertyMap(pConn, pm, TRUE);
|
|
}
|
|
else
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteClassData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteClassData (CSQLConnection *_pConn, DWORD iPropertyId, SQL_ID dObjectId=0, DWORD iArrayPos = -1)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CLASSDATA cd;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = GetFirst_ClassDataByPropertyId(pConn, iPropertyId, cd);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
BOOL bMatch = TRUE;
|
|
if (dObjectId && dObjectId != cd.dObjectId)
|
|
bMatch = FALSE;
|
|
if ((int)iArrayPos >= 0 && iArrayPos != cd.iArrayPos)
|
|
bMatch = FALSE;
|
|
|
|
if (bMatch)
|
|
{
|
|
hr = UpdateClassData_Internal(pConn, cd, TRUE);
|
|
if (FAILED(hr))
|
|
{
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
hr = GetNext_ClassData(pConn, cd);
|
|
|
|
}
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
return hr;
|
|
}
|
|
//***************************************************************************
|
|
//
|
|
// DeleteClassImages
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteClassImages (CSQLConnection *_pConn, DWORD iPropertyId, SQL_ID dObjectId=0, DWORD iArrayPos = -1)
|
|
{
|
|
HRESULT hr = 0;
|
|
CLASSIMAGES cd;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
hr = GetFirst_ClassImagesByPropertyId(pConn, iPropertyId, cd);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
BOOL bMatch = TRUE;
|
|
if (dObjectId && dObjectId != cd.dObjectId)
|
|
bMatch = FALSE;
|
|
if (iArrayPos != -1 && iArrayPos != cd.iArrayPos)
|
|
bMatch = FALSE;
|
|
|
|
if (bMatch)
|
|
{
|
|
hr = UpdateClassImages(pConn, cd, TRUE);
|
|
if (FAILED(hr))
|
|
{
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
hr = GetNext_ClassImages(pConn, cd);
|
|
if (cd.iPropertyId != iPropertyId)
|
|
break;
|
|
}
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteContainerObjs
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteContainerObjs (CSQLConnection *_pConn, SQL_ID dContainerId, SQL_ID dContaineeId )
|
|
{
|
|
HRESULT hr = 0;
|
|
CONTAINEROBJ co;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
if (dContainerId)
|
|
hr = GetFirst_ContainerObjs (pConn, dContainerId, co);
|
|
else
|
|
hr = GetFirst_ContainerObjsByContainee (pConn, dContaineeId, co);
|
|
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
BOOL bMatch = TRUE;
|
|
if (dContainerId && co.dContainerId != dContainerId)
|
|
bMatch = FALSE;
|
|
if (dContaineeId && co.dContaineeId != dContaineeId)
|
|
bMatch = FALSE;
|
|
|
|
if (bMatch)
|
|
hr = UpdateContainerObjs (pConn, co, TRUE);
|
|
|
|
hr = GetNext_ContainerObjs(pConn, co);
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteQualifiers
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteQualifiers (CSQLConnection *_pConn, SQL_ID dObjectId)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CLASSDATA cd;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = GetFirst_ClassData (pConn, dObjectId, cd);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
// Delete any properties with the qualifier flag set.
|
|
|
|
if (cd.iFlags & 2)
|
|
{
|
|
hr = UpdateClassData_Internal(pConn, cd, TRUE);
|
|
if (FAILED(hr))
|
|
{
|
|
cd.Clear();
|
|
goto Exit;
|
|
}
|
|
}
|
|
hr = GetNext_ClassData(pConn, cd);
|
|
if (cd.dObjectId != dObjectId)
|
|
break;
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
Exit:
|
|
|
|
return hr;
|
|
}
|
|
//***************************************************************************
|
|
//
|
|
// DeletePropQualifiers
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeletePropQualifiers (CSQLConnection *_pConn, DWORD iPropertyId)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CLASSDATA cd;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
hr = GetFirst_ClassDataByRefId (pConn, ((SQL_ID)iPropertyId), cd);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
// Delete any properties with the qualifier flag set.
|
|
if (cd.iFlags & 2)
|
|
{
|
|
hr = UpdateClassData_Internal(pConn, cd, TRUE);
|
|
if (FAILED(hr))
|
|
{
|
|
cd.Clear();
|
|
goto Exit;
|
|
}
|
|
}
|
|
hr = GetNext_ClassData(pConn, cd);
|
|
if (cd.iPropertyId != iPropertyId)
|
|
break;
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteIndexData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteIndexData (CSQLConnection *_pConn, DWORD dwStorage, DWORD iPropertyId, SQL_ID dObjectId=0, DWORD iArrayPos = -1)
|
|
{
|
|
HRESULT hr = 0;
|
|
LPWSTR lpTableName = NULL;
|
|
DWORD dwPos = 0;
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
|
|
hr = SetupIndexDataAccessor(pConn, dwStorage, dwPos, &lpTableName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CDeleteMe <wchar_t> d (lpTableName);
|
|
if (!lpTableName || dwStorage == WMIDB_STORAGE_IMAGE)
|
|
return 0;
|
|
|
|
INDEXDATA is;
|
|
JET_TABLEID tableid = pConn->GetTableID(lpTableName);
|
|
|
|
hr = GetFirst_IndexDataByProperty(pConn, iPropertyId, is, tableid, dwPos);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
BOOL bMatch = TRUE;
|
|
if (dObjectId && is.dObjectId != dObjectId)
|
|
bMatch = FALSE;
|
|
if (iArrayPos != -1 && iArrayPos != is.iArrayPos)
|
|
bMatch = FALSE;
|
|
|
|
if (bMatch)
|
|
{
|
|
hr = UpdateIndexData(pConn, is, lpTableName, dwStorage, TRUE);
|
|
if (FAILED(hr))
|
|
{
|
|
is.Clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
hr = GetNext_IndexData(pConn, tableid, dwPos, is);
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
{
|
|
hr = WBEM_S_NO_ERROR;
|
|
break;
|
|
}
|
|
if (iPropertyId != is.iPropertyId)
|
|
break;
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// DeleteObjectMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT DeleteObjectMap (CSQLConnection *_pConn, SQL_ID dObjectId,
|
|
BOOL bDecRef, SQL_ID dScope)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
CESEConnection *pConn = (CESEConnection *)_pConn;
|
|
// Set up the maximum ref count that can exist
|
|
// to physically delete the object.
|
|
|
|
int iMaxRef = 0;
|
|
if (bDecRef)
|
|
iMaxRef = 1;
|
|
OBJECTMAP oj;
|
|
int i;
|
|
|
|
BOOL bDelete = FALSE;
|
|
|
|
hr = GetFirst_ObjectMap(pConn, dObjectId, oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DEBUGTRACE((LOG_WBEMCORE, "DeleteObjectMap %S (RefCount = %ld)\n", oj.sObjectPath, oj.iRefCount));
|
|
|
|
// If we are calling this internally,
|
|
// we need to determine if this is an embedded object
|
|
// or a reference. If an embedded object,
|
|
// always delete it. If a reference, only delete
|
|
// if its in a deleted state, and ref count = 0
|
|
// Otherwise, decrement its ref count.
|
|
|
|
if (dScope)
|
|
{
|
|
if (oj.dObjectScopeId == dScope)
|
|
{
|
|
bDelete = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (bDecRef)
|
|
{
|
|
if (oj.iRefCount > 0)
|
|
oj.iRefCount--;
|
|
}
|
|
if (oj.iObjectState == 2 &&
|
|
!oj.iRefCount)
|
|
{
|
|
bDelete = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (oj.iRefCount <= iMaxRef)
|
|
{
|
|
bDelete = TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (bDecRef)
|
|
oj.iRefCount--;
|
|
oj.iObjectState = 2;
|
|
}
|
|
}
|
|
|
|
// wprintf(L">> Deleting %I64d (%s) \n", dObjectId, (LPWSTR)oj.sObjectKey);
|
|
|
|
if (bDelete)
|
|
{
|
|
// Delete from the INDEX tables...
|
|
|
|
hr = DeleteIndexDataByObjectId(pConn, WMIDB_STORAGE_STRING, dObjectId);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = DeleteIndexDataByObjectId(pConn, WMIDB_STORAGE_NUMERIC, dObjectId);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = DeleteIndexDataByObjectId(pConn, WMIDB_STORAGE_REAL, dObjectId);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = DeleteIndexDataByObjectId(pConn, WMIDB_STORAGE_REFERENCE, dObjectId);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
// If this was an autodelete handle, kill it.
|
|
|
|
hr = DeleteAutoDelete(pConn, dObjectId);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = DeleteReferencePropertiesByClass(pConn, dObjectId);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = DeleteScopeMap(pConn, dObjectId);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
// DELETE CLASSDATA AND CLASSIMAGES
|
|
|
|
SQLIDs ids;
|
|
CLASSDATA cd;
|
|
hr = GetFirst_ClassData(pConn, dObjectId, cd);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
// If this is a reference or an embedded object,
|
|
// decrement ref counts or delete
|
|
|
|
if (cd.dRefId)
|
|
ids.push_back(cd.dRefId);
|
|
|
|
hr = UpdateClassData_Internal(pConn, cd, TRUE);
|
|
if (FAILED(hr))
|
|
{
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
|
|
hr = GetNext_ClassData(pConn, cd);
|
|
if (cd.dObjectId != dObjectId)
|
|
{
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
CLASSIMAGES ci;
|
|
hr = GetFirst_ClassImages(pConn, dObjectId, ci);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
hr = UpdateClassImages(pConn, ci, TRUE);
|
|
if (FAILED(hr))
|
|
{
|
|
ci.Clear();
|
|
break;
|
|
}
|
|
|
|
hr = GetNext_ClassImages(pConn, ci);
|
|
if (ci.dObjectId != dObjectId)
|
|
break;
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
// If this is a class, delete CLASSMAP AND PROPERTYMAP
|
|
|
|
if (oj.dClassId == 1)
|
|
{
|
|
PROPERTYMAP pm;
|
|
hr = GetFirst_PropertyMapByClass(pConn, dObjectId, pm);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
hr = UpdatePropertyMap(pConn, pm, TRUE);
|
|
if (FAILED(hr))
|
|
{
|
|
pm.Clear();
|
|
goto Exit;
|
|
}
|
|
|
|
hr = GetNext_PropertyMap(pConn, pm);
|
|
if (dObjectId != pm.dClassId)
|
|
break;
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = DeleteClassKeys(pConn, dObjectId);
|
|
|
|
CLASSMAP cm;
|
|
hr = GetFirst_ClassMap(pConn, dObjectId, cm);
|
|
if (SUCCEEDED(hr))
|
|
hr = UpdateClassMap(pConn, cm, TRUE);
|
|
cm.Clear();
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
// Remove container memberships
|
|
hr = DeleteContainerObjs (pConn, dObjectId, 0);
|
|
if (SUCCEEDED(hr))
|
|
hr = DeleteContainerObjs (pConn, 0, dObjectId);
|
|
|
|
// Delete or decrement ref counts on
|
|
// references and embedded objects
|
|
|
|
for (i = 0; i < ids.size(); i++)
|
|
{
|
|
hr = DeleteObjectMap(_pConn, ids.at(i), TRUE, dObjectId);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
}
|
|
|
|
// FINALLY, delete from ObjectMap.
|
|
|
|
if (SUCCEEDED(hr))
|
|
hr = UpdateObjectMap(pConn, oj, TRUE);
|
|
}
|
|
|
|
// Otherwise, set the state of this object to "Deleted"
|
|
// and leave it in the tables.
|
|
|
|
else
|
|
hr = UpdateObjectMap(pConn, oj);
|
|
|
|
oj.Clear();
|
|
}
|
|
else
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
Exit:
|
|
|
|
oj.Clear();
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::Delete
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CWmiDbSession::Delete(IWmiDbHandle *pHandle, CSQLConnection *pConn)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
DWORD dwNumRows = 0;
|
|
CWmiDbHandle *pTmp = (CWmiDbHandle *)pHandle;
|
|
bool bLocalTrans = false;
|
|
|
|
if (!m_pController ||
|
|
((CWmiDbController *)m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN)
|
|
return WBEM_E_SHUTTING_DOWN;
|
|
|
|
SQL_ID dID = pTmp->m_dObjectId;
|
|
SQL_ID dClassID = pTmp->m_dClassId;
|
|
|
|
hr = VerifyObjectLock(dID, pTmp->m_dwHandleType, pTmp->m_dwVersion);
|
|
if (FAILED(hr) && IsDistributed())
|
|
{
|
|
if (LockExists(dID))
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (!pConn && m_pController)
|
|
{
|
|
bLocalTrans = true;
|
|
hr = GetSQLCache()->GetConnection(&pConn, TRUE, IsDistributed());
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = Delete(dID, pConn);
|
|
|
|
if (bLocalTrans && m_pController)
|
|
GetSQLCache()->ReleaseConnection(pConn, hr, IsDistributed());
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
HRESULT AddToSQLIDs (SQL_ID dID, SQLIDs *pToDel)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
BOOL bFound = FALSE;
|
|
for (int i = 0; i < pToDel->size(); i++)
|
|
{
|
|
if (pToDel->at(i) == dID)
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!bFound)
|
|
pToDel->push_back(dID);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT GetIdsToDelete (SQL_ID dID, CSQLConnection *pConn, SQLIDs *pToDel)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
OBJECTMAP om;
|
|
SQLIDs NewList;
|
|
|
|
hr = GetFirst_ObjectMap(pConn, dID, om);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Decrement ref counts on reference properties.
|
|
|
|
CLASSDATA cd;
|
|
SQLIDs ToUpd;
|
|
hr = GetFirst_ClassDataByRefId(pConn, dID, cd);
|
|
while (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
ToUpd.push_back(cd.dObjectId);
|
|
hr = GetNext_ClassData(pConn, cd);
|
|
if (cd.dRefId != dID)
|
|
{
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
|
|
for (int i = 0; i < ToUpd.size(); i++)
|
|
{
|
|
hr = GetFirst_ObjectMap(pConn, ToUpd.at(i), om);
|
|
if (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
if (om.iRefCount > 0)
|
|
om.iRefCount--;
|
|
hr = UpdateObjectMap(pConn, om);
|
|
om.Clear();
|
|
}
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
hr = GetFirst_ObjectMapByScope(pConn, dID, om);
|
|
while (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
SQL_ID dSubId = om.dObjectId;
|
|
|
|
AddToSQLIDs(dSubId, &NewList);
|
|
|
|
hr = GetNext_ObjectMap(pConn, om);
|
|
if (om.dObjectScopeId != dID)
|
|
break;
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
// Classes
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = GetFirst_ObjectMapByClass(pConn, dID, om);
|
|
while (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
SQL_ID dSubId = om.dObjectId;
|
|
AddToSQLIDs(dSubId, &NewList);
|
|
|
|
hr = GetNext_ObjectMap(pConn, om);
|
|
if (om.dClassId != dID)
|
|
{
|
|
om.Clear();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
// Then all subclasses
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CLASSMAP cd;
|
|
|
|
hr = GetFirst_ClassMapBySuperClass(pConn, dID, cd);
|
|
while (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
SQL_ID dSubId = cd.dClassId;
|
|
AddToSQLIDs(dSubId, &NewList);
|
|
|
|
hr = GetNext_ClassMap(pConn, cd);
|
|
if (dID != cd.dSuperClassId)
|
|
{
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
for (int j = 0; j < NewList.size(); j++)
|
|
{
|
|
hr = GetIdsToDelete(NewList.at(j), pConn, pToDel);
|
|
AddToSQLIDs(NewList.at(j), pToDel);
|
|
}
|
|
|
|
om.Clear();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CheckSecurity(SQLIDs *pToDel, CWmiDbSession *pSession, CSQLConnection *pConn)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
for (int i = 0; i < pToDel->size(); i++)
|
|
{
|
|
OBJECTMAP om;
|
|
hr = GetFirst_ObjectMap(pConn, pToDel->at(i), om);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pSession->VerifyObjectSecurity(pConn, pToDel->at(i), om.dClassId, om.dObjectScopeId, 0,
|
|
pSession->GetSchemaCache()->GetWriteToken(pToDel->at(i), om.dClassId));
|
|
if (FAILED(hr) && hr != WBEM_E_NOT_FOUND)
|
|
break;
|
|
om.Clear();
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::Delete
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CWmiDbSession::Delete(SQL_ID dID, CSQLConnection *pConn)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
int iPos = 0, iMax = 100;
|
|
SQL_ID dClassId = 0, dScopeId = 0, dObjId = 0;
|
|
DWORD dwNumRows = 0;
|
|
wchar_t wBuffer1[550], wBuffer2[550];
|
|
int iToUpd = 0, iToDel = 0;
|
|
SQLIDs ToDel;
|
|
|
|
// We need to enumerate every object that is underneath this one
|
|
// in the hierarchy, and delete them one-by-one.
|
|
// This function needs to recurse through all children,
|
|
// remove the data from the tables, fix reference counts,
|
|
// and clean the caches. If all that worked, we can commit.
|
|
// ===========================================================
|
|
|
|
hr = GetIdsToDelete(dID, pConn, &ToDel);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
AddToSQLIDs(dID, &ToDel);
|
|
hr = CheckSecurity(&ToDel, this, pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
for (int i = 0; i < ToDel.size(); i++)
|
|
{
|
|
hr = DeleteObjectMap(pConn, ToDel.at(i));
|
|
if (FAILED(hr))
|
|
break;
|
|
GetSchemaCache()->DeleteClass(ToDel.at(i));
|
|
CleanCache(ToDel.at(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::GetClassObject
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CWmiDbSession::GetClassObject (CSQLConnection *pConn, SQL_ID dClassId, IWbemClassObject **ppObj)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
_IWmiObject *pNew = NULL;
|
|
SQL_ID dParentId = 0;
|
|
|
|
// All we need to do is read the blob from the database.
|
|
// This should be cached where space allows.
|
|
|
|
CLASSMAP cm;
|
|
|
|
BOOL bNeedToRelease = FALSE;
|
|
|
|
if (!pConn && m_pController)
|
|
{
|
|
hr = GetSQLCache()->GetConnection(&pConn, 0, IsDistributed());
|
|
bNeedToRelease = TRUE;
|
|
if (FAILED(hr))
|
|
return hr;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = GetFirst_ClassMap(pConn, dClassId, cm);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (cm.dSuperClassId != 0 && cm.dSuperClassId != 1)
|
|
{
|
|
hr = GetObjectCache()->GetObject(cm.dSuperClassId, ppObj);
|
|
if (FAILED(hr))
|
|
hr = GetClassObject(pConn, cm.dSuperClassId, ppObj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Merge the class part.
|
|
|
|
_IWmiObject *pObj = (_IWmiObject *)*ppObj;
|
|
if (pObj)
|
|
{
|
|
hr = pObj->Merge (WMIOBJECT_MERGE_FLAG_CLASS, cm.dwBufferLen, cm.pClassBuffer, &pNew);
|
|
pObj->Release();
|
|
if (SUCCEEDED(hr))
|
|
*ppObj = pNew;
|
|
}
|
|
else
|
|
hr = WBEM_E_FAILED;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_IWmiObject *pObj = NULL;
|
|
hr = CoCreateInstance(CLSID_WbemClassObject, NULL, CLSCTX_INPROC_SERVER,
|
|
IID__IWmiObject, (void **)&pObj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pObj->Merge(WMIOBJECT_MERGE_FLAG_CLASS, cm.dwBufferLen, cm.pClassBuffer, &pNew);
|
|
pObj->Release();
|
|
if (SUCCEEDED(hr))
|
|
*ppObj = pNew;
|
|
}
|
|
}
|
|
|
|
cm.Clear();
|
|
}
|
|
}
|
|
|
|
if (bNeedToRelease && pConn && m_pController)
|
|
{
|
|
GetSQLCache()->ReleaseConnection(pConn, hr, IsDistributed());
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::GetObjectData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CWmiDbSession::GetObjectData (CSQLConnection *pConn, SQL_ID dObjectId, SQL_ID dClassId,
|
|
SQL_ID dScopeId, DWORD dwHandleType, DWORD &dwVersion,
|
|
IWbemClassObject **ppObj, BOOL bNoDefaults, LPWSTR lpInKey,
|
|
BOOL bGetSD )
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
_bstr_t sClassPath;
|
|
DWORD dwGenus = 1;
|
|
DWORD dwRows;
|
|
bool bUsedCache = false;
|
|
LPWSTR lpKey = NULL;
|
|
|
|
DWORD dwType = 0, dwVer = 0;
|
|
|
|
if (!m_pController ||
|
|
((CWmiDbController *)m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN)
|
|
return WBEM_E_SHUTTING_DOWN;
|
|
|
|
// Validate version if this is a versioned handle.
|
|
// ================================================-
|
|
|
|
try
|
|
{
|
|
if (!bNoDefaults)
|
|
{
|
|
hr = VerifyObjectLock(dObjectId, dwHandleType, dwVersion);
|
|
if (FAILED(hr) && IsDistributed())
|
|
{
|
|
if (LockExists(dObjectId))
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Check the object cache to see if this
|
|
// IWbemClassObject is already loaded.
|
|
// Never cache an instance of __Instances
|
|
// =====================================
|
|
|
|
if (dClassId == INSTANCESCLASSID)
|
|
hr = WBEM_E_NOT_FOUND;
|
|
else
|
|
hr = GetObjectCache()->GetObject(dObjectId, ppObj);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
// Otherwise, we need to hit the database.
|
|
// =======================================
|
|
|
|
VARIANT vTemp;
|
|
VariantInit(&vTemp);
|
|
|
|
if (dClassId == 1)
|
|
{
|
|
dwGenus = 1;
|
|
dClassId = dObjectId;
|
|
}
|
|
else
|
|
dwGenus = 2;
|
|
|
|
SQL_ID dTemp = 0;
|
|
|
|
|
|
// We now have an object path and class ID.
|
|
// Now we have to instantiate a new IWbemClassObject,
|
|
// populate all the system properties
|
|
// ==================================================
|
|
|
|
IWbemClassObject *pClass = NULL;
|
|
IWbemClassObject *pTemp = NULL;
|
|
|
|
hr = GetObjectCache()->GetObject(dClassId, &pClass);
|
|
if (SUCCEEDED(hr))
|
|
bUsedCache = true;
|
|
else
|
|
hr = GetClassObject(pConn, dClassId, &pClass);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (dwGenus == 2)
|
|
{
|
|
if (pClass)
|
|
pClass->SpawnInstance(0, &pTemp);
|
|
{
|
|
if (pTemp)
|
|
hr = GetSchemaCache()->DecorateWbemObj(m_sMachineName, m_sNamespacePath,
|
|
dScopeId, pTemp, dClassId);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pTemp = pClass;
|
|
|
|
hr = GetSchemaCache()->DecorateWbemObj(m_sMachineName, m_sNamespacePath,
|
|
dScopeId, pTemp, dClassId);
|
|
|
|
}
|
|
|
|
// Special case if this is an __Instances container,
|
|
// We need to instantiate an instance of __Instances,
|
|
// and plug the class name into the ClassName property.
|
|
// ===================================================
|
|
|
|
if (dClassId == INSTANCESCLASSID)
|
|
{
|
|
_bstr_t sName, sPath;
|
|
SQL_ID dTemp1, dTemp2;
|
|
DWORD dwFlags;
|
|
|
|
hr = GetSchemaCache()->GetClassInfo (dObjectId, sPath, dTemp1, dTemp2, dwFlags, &sName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
VARIANT vTemp;
|
|
VariantInit(&vTemp);
|
|
vTemp.bstrVal = SysAllocString(sName);
|
|
vTemp.vt = VT_BSTR;
|
|
pTemp->Put(L"ClassName", 0, &vTemp, CIM_STRING);
|
|
VariantClear(&vTemp);
|
|
*ppObj = pTemp;
|
|
}
|
|
else
|
|
{
|
|
pTemp->Release();
|
|
pTemp = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (lpInKey)
|
|
{
|
|
hr = GetObjectData2 (pConn, dObjectId, dClassId, dScopeId, pTemp, FALSE, NULL);
|
|
lpKey = lpInKey;
|
|
}
|
|
else
|
|
hr = GetObjectData2 (pConn, dObjectId, dClassId, dScopeId, pTemp, FALSE, &lpKey);
|
|
|
|
if (dwGenus == 2)
|
|
{
|
|
if (!bUsedCache && SUCCEEDED(hr) && !((dwHandleType & 0xF00) == WMIDB_HANDLE_TYPE_NO_CACHE))
|
|
{
|
|
if (lpKey)
|
|
{
|
|
LPWSTR lpEqual = wcsrchr(lpKey, L'.');
|
|
if (!lpEqual)
|
|
lpEqual = wcsrchr(lpKey, L'=');
|
|
|
|
if (lpEqual)
|
|
{
|
|
LPWSTR lpPath = Macro_CloneLPWSTR(lpKey);
|
|
if (lpPath)
|
|
{
|
|
CDeleteMe <wchar_t> d10 (lpPath);
|
|
int iPos = lpEqual - lpKey;
|
|
lpPath[iPos] = L'\0';
|
|
|
|
GetObjectCache()->PutObject(dClassId, 1, dScopeId, lpPath, 1, pClass);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
pTemp->Release();
|
|
pTemp = NULL;
|
|
}
|
|
|
|
*ppObj = pTemp;
|
|
|
|
}
|
|
|
|
if (dwGenus == 2 && pClass)
|
|
pClass->Release();
|
|
}
|
|
|
|
// If all that worked, try and cache this object.
|
|
// ==============================================
|
|
|
|
if (SUCCEEDED(hr) && ppObj && (dwHandleType & 0xF00) && dClassId != INSTANCESCLASSID)
|
|
{
|
|
// This is allowed to fail, since its *just* a cache.
|
|
if ((dwHandleType & 0xF00) != WMIDB_HANDLE_TYPE_NO_CACHE && lpKey)
|
|
{
|
|
bool bCacheType = ((dwHandleType & 0xF00) == WMIDB_HANDLE_TYPE_STRONG_CACHE) ? 1 : 0;
|
|
|
|
GetObjectCache()->PutObject(dObjectId, dClassId, dScopeId, lpKey, bCacheType, *ppObj);
|
|
}
|
|
}
|
|
|
|
if (!lpInKey)
|
|
delete lpKey;
|
|
}
|
|
else
|
|
{
|
|
// Make sure the decoration is up-to-date.
|
|
hr = GetSchemaCache()->DecorateWbemObj(m_sMachineName, m_sNamespacePath,
|
|
dScopeId, *ppObj, dClassId);
|
|
}
|
|
|
|
// Populate the security descriptor, if requested
|
|
if (SUCCEEDED(hr) && bGetSD)
|
|
{
|
|
BOOL bNeedToRelease = FALSE;
|
|
|
|
if (!pConn && m_pController)
|
|
{
|
|
hr = GetSQLCache()->GetConnection(&pConn, 0, FALSE);
|
|
bNeedToRelease = TRUE;
|
|
if (FAILED(hr))
|
|
{
|
|
(*ppObj)->Release();
|
|
*ppObj = NULL;
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
PNTSECURITY_DESCRIPTOR pSD = NULL;
|
|
DWORD dwLen = 0;
|
|
if (SUCCEEDED(CSQLExecProcedure::GetSecurityDescriptor(pConn, dObjectId, &pSD, dwLen, 0)))
|
|
{
|
|
((_IWmiObject *)*ppObj)->WriteProp(L"__SECURITY_DESCRIPTOR", 0, dwLen, dwLen, CIM_UINT8|CIM_FLAG_ARRAY, pSD);
|
|
|
|
delete pSD;
|
|
}
|
|
if (bNeedToRelease && pConn && m_pController)
|
|
{
|
|
GetSQLCache()->ReleaseConnection(pConn, hr, FALSE);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
hr = WBEM_E_SHUTTING_DOWN;
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::GetObjectData2
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CWmiDbSession::GetObjectData2 (CSQLConnection *pConn, SQL_ID dObjectId, SQL_ID dClassId, SQL_ID dScopeId,
|
|
IWbemClassObject *pObj, BOOL bNoDefaults, LPWSTR * lpKey)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
BOOL bNeedToRelease = FALSE;
|
|
|
|
if (!pObj)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
if (!pConn && m_pController)
|
|
{
|
|
hr = GetSQLCache()->GetConnection(&pConn, 0, FALSE);
|
|
bNeedToRelease = TRUE;
|
|
if (FAILED(hr))
|
|
return hr;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (lpKey)
|
|
{
|
|
OBJECTMAP oj;
|
|
|
|
hr = GetFirst_ObjectMap(pConn, dObjectId, oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (oj.iObjectState == 2)
|
|
{
|
|
DEBUGTRACE((LOG_WBEMCORE, "Object %I64d is marked as deleted\n", dObjectId));
|
|
oj.Clear();
|
|
return WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
if (oj.sObjectKey)
|
|
{
|
|
LPWSTR lpKey2 = new wchar_t [wcslen(oj.sObjectKey)+1];
|
|
if (lpKey2)
|
|
{
|
|
wcscpy(lpKey2, oj.sObjectKey);
|
|
*lpKey = lpKey2;
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_OBJECT;
|
|
|
|
oj.Clear();
|
|
}
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
if (dClassId != 1 && dClassId != dObjectId)
|
|
{
|
|
CLASSDATA cd;
|
|
DWORD dwRows;
|
|
BOOL bBigText = FALSE, bObjProp = FALSE;
|
|
int i = 0;
|
|
Properties props;
|
|
|
|
typedef std::vector<CLASSDATA *> CDs;
|
|
CDs cds;
|
|
|
|
hr = GetFirst_ClassData(pConn, dObjectId, cd, -1, TRUE, GetSchemaCache());
|
|
while (SUCCEEDED(hr) && hr != WBEM_S_NO_MORE_DATA)
|
|
{
|
|
SetObjectData(pConn, pObj, this, &((CWmiDbController *)m_pController)->SchemaCache,
|
|
cd, FALSE, bBigText, &bObjProp, bNoDefaults);
|
|
if (bObjProp)
|
|
{
|
|
CLASSDATA *pCD = new CLASSDATA;
|
|
*pCD = cd;
|
|
cds.push_back(pCD);
|
|
}
|
|
hr = GetNext_ClassData(pConn, cd, -1, TRUE, GetSchemaCache());
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
// The embedded object properties, since there will
|
|
// be a move next conflict if we try to retrieve them earlier.
|
|
|
|
for (i = 0; i < cds.size(); i++)
|
|
{
|
|
CLASSDATA *pCD = cds.at(i);
|
|
SetObjectData(pConn, pObj, this, &((CWmiDbController *)m_pController)->SchemaCache,
|
|
*pCD, FALSE, bBigText, NULL, bNoDefaults);
|
|
pCD->Clear();
|
|
delete pCD;
|
|
}
|
|
|
|
//if (bBigText || GetSchemaCache()->HasImageProp(dClassId))
|
|
{
|
|
// Finally, anything stored as long binary data.
|
|
|
|
DWORD dwSecurity = 0;
|
|
GetSchemaCache()->GetPropertyID(L"__SECURITY_DESCRIPTOR", 1,
|
|
0, REPDRVR_IGNORE_CIMTYPE, dwSecurity);
|
|
|
|
CLASSIMAGES ci;
|
|
|
|
hr = GetFirst_ClassImages(pConn, dObjectId, ci);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (ci.iPropertyId != dwSecurity)
|
|
{
|
|
// Stuff this blob into the object.
|
|
cd.Copy(ci);
|
|
SetObjectData(pConn, pObj, this, &((CWmiDbController *)m_pController)->SchemaCache,
|
|
cd, TRUE, bBigText, NULL, bNoDefaults);
|
|
cd.Clear();
|
|
}
|
|
|
|
hr = GetNext_ClassImages(pConn, ci);
|
|
if (ci.dObjectId != dObjectId)
|
|
break;
|
|
}
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
}
|
|
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
Exit:
|
|
if (bNeedToRelease && pConn && m_pController)
|
|
{
|
|
GetSQLCache()->ReleaseConnection(pConn, hr, IsDistributed());
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::GetHierarchy
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::GetHierarchy(CSQLConnection *pConn, SQL_ID dClassId)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
// Not required for Jet.
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::GetNextUnkeyedPath
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::GetNextUnkeyedPath(CSQLConnection *pConn, SQL_ID dClassId, _bstr_t &sNewPath)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Generate a GUID for this object, and use this an artificial path.
|
|
// The format doesn't matter to us internally.
|
|
|
|
GUID guid;
|
|
LPWSTR lpNewPath;
|
|
|
|
hr = CoCreateGuid(&guid);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = UuidToString(&guid, &lpNewPath);
|
|
if (SUCCEEDED(hr))
|
|
sNewPath = lpNewPath;
|
|
RpcStringFree(&lpNewPath);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::GetNextKeyhole
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::GetNextKeyhole(CSQLConnection *pConn2, DWORD iPropertyId, SQL_ID &dNewId)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
CESEConnection *pConn = (CESEConnection *)pConn2;
|
|
|
|
// Here we need to select the largest value plus one currently
|
|
// in the table for this property ID.
|
|
// If null, its one.
|
|
|
|
dNewId = 1;
|
|
JET_SESID session = pConn->GetSessionID();
|
|
JET_TABLEID tableid = pConn->GetTableID(L"IndexNumericData");
|
|
|
|
JET_ERR err = JetSetCurrentIndex(session, tableid, "PropertyId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMove(session, tableid, JET_MoveLast, 0);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
INDEXDATA is;
|
|
hr = GetIndexData(pConn, session, tableid, 0, is);
|
|
dNewId = is.dValue + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
|
|
if (dNewId == 1)
|
|
{
|
|
tableid = pConn->GetTableID(L"IndexStringData");
|
|
err = JetSetCurrentIndex(session, tableid, "PropertyId_idx");
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMakeKey(session, tableid, &iPropertyId, sizeof(DWORD), JET_bitNewKey);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetSeek( session, tableid, JET_bitSeekEQ );
|
|
if (err == JET_errSuccess)
|
|
{
|
|
err = JetMove(session, tableid, JET_MoveLast, 0);
|
|
if (err == JET_errSuccess)
|
|
{
|
|
INDEXDATA is;
|
|
hr = GetIndexData(pConn, session, tableid, 0, is);
|
|
dNewId = _wtoi64(is.sValue) + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
hr = CSQLExecute::GetWMIError(err);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::GetObjectIdByPath
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::GetObjectIdByPath (CSQLConnection *pConn, LPCWSTR lpPath,
|
|
SQL_ID &dObjectId, SQL_ID &dClassId, SQL_ID *dScopeId, BOOL *bDeleted)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
if (!pConn)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
if (!dObjectId && lpPath)
|
|
dObjectId = CRC64::GenerateHashValue(lpPath);
|
|
|
|
OBJECTMAP oj;
|
|
|
|
hr = GetFirst_ObjectMap(pConn, dObjectId, oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
dClassId = oj.dClassId;
|
|
if (dScopeId)
|
|
*dScopeId = oj.dObjectScopeId;
|
|
if (bDeleted)
|
|
{
|
|
if (oj.iObjectState == 2)
|
|
*bDeleted = TRUE;
|
|
}
|
|
oj.Clear();
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::DeleteProperty
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::DeleteProperty(CSQLConnection *pConn, DWORD iPropertyId)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// This has to clean up reference counts, if any of these properties
|
|
// are references. If its an embedded object, we need to remove
|
|
// all of the instances.
|
|
// Remove data from all index tables and Class Data. Then remove from
|
|
// PropertyMap.
|
|
// We can't allow them to delete a key property if there are instances.
|
|
// We have to delete qualifiers on the property (Flags&2, RefId = PropertyId)
|
|
// If a reference, delete object if the ref count is zero.
|
|
|
|
PROPERTYMAP pm;
|
|
|
|
hr = GetFirst_PropertyMap(pConn, iPropertyId, pm);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (pm.iFlags & REPDRVR_FLAG_KEY)
|
|
{
|
|
// We can't remove a key when the class has instances.
|
|
CLASSDATA cd;
|
|
|
|
hr = GetFirst_ClassDataByPropertyId (pConn, iPropertyId, cd);
|
|
if (SUCCEEDED(hr))
|
|
hr = WBEM_E_INVALID_OPERATION;
|
|
cd.Clear();
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// We need to decrement reference counts on
|
|
// references we are deleting, delete
|
|
// deleted references with a zero ref count,
|
|
// and remove embedded objects
|
|
|
|
if (pm.iStorageTypeId == CIM_OBJECT || pm.iStorageTypeId == CIM_REFERENCE)
|
|
{
|
|
CLASSDATA cd;
|
|
SQLIDs ids;
|
|
|
|
hr = GetFirst_ClassDataByPropertyId (pConn, iPropertyId, cd);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
ids.push_back(cd.dObjectId);
|
|
hr = GetNext_ClassData(pConn, cd);
|
|
if (cd.iPropertyId != iPropertyId)
|
|
{
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < ids.size(); i++)
|
|
{
|
|
// Embedded objects are deleted
|
|
|
|
if (pm.iStorageTypeId == CIM_OBJECT)
|
|
hr = DeleteObjectMap(pConn, ids.at(i), TRUE);
|
|
|
|
// References have ref counts decremented.
|
|
// If their reference count is zero, and they are
|
|
// marked deleted, delete them now.
|
|
|
|
else if (pm.iStorageTypeId == CIM_REFERENCE)
|
|
{
|
|
OBJECTMAP oj;
|
|
hr = GetFirst_ObjectMap(pConn, ids.at(i), oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (oj.iRefCount <= 1 && oj.iObjectState == 2)
|
|
hr = DeleteObjectMap(pConn, ids.at(i), TRUE);
|
|
else
|
|
{
|
|
oj.iRefCount--;
|
|
hr = UpdateObjectMap(pConn, oj, FALSE);
|
|
}
|
|
oj.Clear();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Remove all data for this property..
|
|
|
|
if (pm.iFlags & (REPDRVR_FLAG_KEY + REPDRVR_FLAG_INDEXED))
|
|
hr = DeleteIndexData(pConn, pm.iStorageTypeId, iPropertyId);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Delete qualifiers on this property.
|
|
|
|
hr = DeletePropQualifiers(pConn, iPropertyId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Delete all associated data.
|
|
hr = DeleteClassData(pConn, iPropertyId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = DeleteClassImages(pConn, iPropertyId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = DeletePropertyMap(pConn, iPropertyId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = DeleteClassKeys(pConn, 0, iPropertyId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
hr = WBEM_S_NO_ERROR; // OK if not found.
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::DeleteInstanceData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::DeleteInstanceData (CSQLConnection *pConn, SQL_ID dObjectId,
|
|
DWORD iPropertyId, DWORD iPos)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
IRowset *pIRowset = NULL;
|
|
DWORD dwNumRows = 0;
|
|
wchar_t wSQL[512];
|
|
|
|
PROPERTYMAP pm;
|
|
|
|
IAccessor *pAccessor = NULL;
|
|
HACCESSOR hAcc = NULL;
|
|
|
|
hr = GetFirst_PropertyMap(pConn, iPropertyId, pm);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (pm.iFlags & (REPDRVR_FLAG_KEY + REPDRVR_FLAG_NOT_NULL))
|
|
hr = WBEM_E_INVALID_OPERATION;
|
|
else
|
|
{
|
|
if (pm.iStorageTypeId == CIM_OBJECT || pm.iStorageTypeId == CIM_REFERENCE)
|
|
{
|
|
CLASSDATA cd;
|
|
SQLIDs ids;
|
|
|
|
hr = GetFirst_ClassDataByPropertyId (pConn, iPropertyId, cd);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
ids.push_back(cd.dObjectId);
|
|
hr = GetNext_ClassData(pConn, cd);
|
|
if (cd.iPropertyId != iPropertyId)
|
|
{
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < ids.size(); i++)
|
|
{
|
|
// Embedded objects are deleted
|
|
|
|
if (pm.iStorageTypeId == CIM_OBJECT)
|
|
hr = DeleteObjectMap(pConn, ids.at(i), TRUE);
|
|
|
|
// References have ref counts decremented.
|
|
// If their reference count is zero, and they are
|
|
// marked deleted, delete them now.
|
|
|
|
else if (pm.iStorageTypeId == CIM_REFERENCE)
|
|
{
|
|
OBJECTMAP oj;
|
|
hr = GetFirst_ObjectMap(pConn, ids.at(i), oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (oj.iRefCount <= 1 && oj.iObjectState == 2)
|
|
hr = DeleteObjectMap(pConn, ids.at(i), TRUE);
|
|
else
|
|
{
|
|
oj.iRefCount--;
|
|
hr = UpdateObjectMap(pConn, oj, FALSE);
|
|
}
|
|
oj.Clear();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = DeleteIndexData(pConn, pm.iStorageTypeId, iPropertyId, dObjectId, iPos);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = DeleteClassImages(pConn, iPropertyId, dObjectId, iPos);
|
|
if (SUCCEEDED(hr))
|
|
hr = DeleteClassData(pConn, iPropertyId, dObjectId, iPos);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::CheckKeyMigration
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::CheckKeyMigration(CSQLConnection *pConn, LPWSTR lpObjectKey, LPWSTR lpClassName, SQL_ID dClassId,
|
|
SQL_ID dScopeID, SQL_ID *pIDs, DWORD iNumIDs)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Make sure this object does not already exist with the same scope and different ClassID.
|
|
|
|
SQL_ID dObjId = CRC64::GenerateHashValue(lpObjectKey);
|
|
|
|
OBJECTMAP oj;
|
|
hr = GetFirst_ObjectMap(pConn, dObjId, oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (oj.dObjectScopeId == dScopeID &&
|
|
dClassId != oj.dClassId)
|
|
hr = WBEM_E_ALREADY_EXISTS;
|
|
|
|
oj.Clear();
|
|
}
|
|
else if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR; // OK if not found.
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CSQLExecProcedure::NeedsToCheckKeyMigration(BOOL &bCheck)
|
|
{
|
|
bCheck = TRUE;
|
|
return 0;
|
|
}
|
|
|
|
|
|
HRESULT CSQLExecProcedure::Execute (CSQLConnection *pConn, LPCWSTR lpProcName, CWStringArray &arrValues,
|
|
IRowset **ppIRowset)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::HasInstances
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::HasInstances(CSQLConnection *pConn, SQL_ID dClassId, SQL_ID *pDerivedIds, DWORD iNumDerived, BOOL &bInstancesExist)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
bInstancesExist = FALSE;
|
|
|
|
// We need to query the table for any instance of this class
|
|
// or any of its children.
|
|
|
|
OBJECTMAP oj;
|
|
|
|
hr = GetFirst_ObjectMapByClass(pConn, dClassId, oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (oj.iObjectState == 0)
|
|
{
|
|
bInstancesExist = TRUE;
|
|
break;
|
|
}
|
|
hr = GetNext_ObjectMap(pConn, oj);
|
|
if (oj.dClassId != dClassId)
|
|
break;
|
|
}
|
|
oj.Clear();
|
|
}
|
|
|
|
if (!bInstancesExist)
|
|
{
|
|
for (int i = 0; i < iNumDerived; i++)
|
|
{
|
|
hr = GetFirst_ObjectMapByClass(pConn, pDerivedIds[i], oj);
|
|
while (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
if (oj.iObjectState == 0)
|
|
{
|
|
bInstancesExist = TRUE;
|
|
break;
|
|
}
|
|
hr = GetNext_ObjectMap(pConn, oj);
|
|
if (pDerivedIds[i] != oj.dClassId)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::InsertClass
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::InsertClass (CSQLConnection *pConn, LPCWSTR lpClassName, LPCWSTR lpObjectKey, LPCWSTR lpObjectPath, SQL_ID dScopeID,
|
|
SQL_ID dParentClassId, SQL_ID dDynasty, DWORD iState, BYTE *pClassBuff, DWORD dwClassBuffLen, DWORD iClassFlags, DWORD iInsertFlags, SQL_ID &dNewId)
|
|
{
|
|
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
SQL_ID dClassId = 0;
|
|
BOOL bExists = FALSE;
|
|
BOOL bDeleted = FALSE;
|
|
OBJECTMAP oj;
|
|
|
|
if (!dNewId)
|
|
dNewId = CRC64::GenerateHashValue(lpObjectKey);
|
|
|
|
if (!dDynasty)
|
|
dDynasty = dNewId; // Reports to self.
|
|
|
|
hr = GetFirst_ObjectMap(pConn, dNewId, oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
dClassId = oj.dClassId;
|
|
bExists = TRUE;
|
|
if (bDeleted && (iInsertFlags & WBEM_FLAG_UPDATE_ONLY))
|
|
hr = WBEM_E_INVALID_OBJECT;
|
|
else if (iInsertFlags & WBEM_FLAG_CREATE_ONLY && (!bDeleted))
|
|
hr = WBEM_E_ALREADY_EXISTS;
|
|
else
|
|
hr = WBEM_S_NO_ERROR;
|
|
oj.Clear();
|
|
}
|
|
else if (iInsertFlags & WBEM_FLAG_UPDATE_ONLY)
|
|
hr = WBEM_E_INVALID_OBJECT;
|
|
else
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
if (dClassId != 1 && dParentClassId == 0)
|
|
dParentClassId = 1;
|
|
else if (dParentClassId == dNewId)
|
|
hr = WBEM_E_CIRCULAR_REFERENCE;
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
BOOL bInsert = TRUE;
|
|
if (bExists)
|
|
bInsert = FALSE;
|
|
|
|
if (!dNewId)
|
|
dNewId = CRC64::GenerateHashValue(lpObjectKey);
|
|
|
|
LPWSTR lpPath = StripQuotes((LPWSTR)lpObjectPath);
|
|
CDeleteMe <wchar_t> d (lpPath);
|
|
|
|
// Insert ObjectMap
|
|
hr = InsertObjectMap(pConn, dNewId, lpObjectKey, iState, lpPath, dScopeID, iClassFlags, 0, 1, bInsert);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = InsertClassMap(pConn, dNewId, lpClassName, dParentClassId, dDynasty, pClassBuff, dwClassBuffLen, bInsert);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (iInsertFlags & WMIDB_HANDLE_TYPE_AUTODELETE)
|
|
{
|
|
hr = InsertAutoDelete(pConn, dNewId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::InsertClassData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::InsertClassData (CSQLConnection *pConn, IWbemClassObject *pObj, CSchemaCache *pCache, SQL_ID dScopeId,
|
|
SQL_ID dClassId, LPCWSTR lpPropName,
|
|
DWORD CIMType, DWORD StorageType,LPCWSTR lpValue, SQL_ID dRefClassId, DWORD iPropID,
|
|
DWORD iFlags, DWORD iFlavor, BOOL iSkipValid, DWORD &iNewPropId, SQL_ID dOrigClassId,
|
|
BOOL *bIsKey)
|
|
{
|
|
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
SQL_ID dClass = dOrigClassId;
|
|
if (!dClass)
|
|
dClass = dClassId;
|
|
DWORD dwNumRows = 0;
|
|
BOOL bHasKey = FALSE;
|
|
|
|
if (iFlags & REPDRVR_FLAG_QUALIFIER)
|
|
dClass = 1;
|
|
|
|
if (iNewPropId)
|
|
{
|
|
BOOL bLocal = FALSE;
|
|
BOOL bKey = pCache->IsKey(dClassId, iNewPropId, bLocal);
|
|
|
|
PROPERTYMAP pm;
|
|
hr = GetFirst_PropertyMap(pConn, iNewPropId, pm);
|
|
if (SUCCEEDED(hr) && pm.iStorageTypeId != StorageType)
|
|
{
|
|
if (StorageType == WMIDB_STORAGE_REAL &&
|
|
pm.iStorageTypeId == WMIDB_STORAGE_NUMERIC)
|
|
{
|
|
hr = InsertPropertyMap(pConn, iNewPropId, dClassId, StorageType,
|
|
CIMType, lpPropName, iFlags, FALSE);
|
|
|
|
// They changed the datatype. If this used to be an int,
|
|
// (the only acceptable move) we have to move the data,
|
|
// including any default and index, to the new column, table.
|
|
|
|
CLASSDATA pm;
|
|
|
|
hr = GetFirst_ClassDataByPropertyId(pConn, iNewPropId, pm);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
pm.rPropertyRealValue = pm.dPropertyNumericValue;
|
|
pm.dPropertyNumericValue = 0;
|
|
|
|
hr = UpdateClassData_Internal(pConn, pm);
|
|
if (FAILED(hr))
|
|
{
|
|
pm.Clear();
|
|
break;
|
|
}
|
|
|
|
hr = GetNext_ClassData(pConn, pm);
|
|
if (pm.iPropertyId != iNewPropId)
|
|
{
|
|
pm.Clear();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (iFlags & (REPDRVR_FLAG_INDEXED + REPDRVR_FLAG_KEY))
|
|
{
|
|
INDEXDATA id;
|
|
JET_TABLEID tid = 0;
|
|
DWORD dwPos = 0;
|
|
|
|
hr = GetFirst_IndexDataByProperty(pConn, iNewPropId, id,
|
|
tid, dwPos);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
hr = InsertIndexData(pConn, dClassId, iNewPropId, id.iArrayPos,
|
|
id.sValue, id.dValue, id.rValue, WMIDB_STORAGE_REAL);
|
|
if (FAILED(hr))
|
|
break;
|
|
|
|
hr = GetNext_IndexData(pConn, tid, dwPos, id);
|
|
}
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
if (SUCCEEDED(hr))
|
|
DeleteIndexData(pConn, WMIDB_STORAGE_NUMERIC, iNewPropId);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_INVALID_OPERATION;
|
|
}
|
|
|
|
if (dRefClassId)
|
|
hr = InsertReferenceProperties (pConn, dClassId, iNewPropId, dRefClassId, FALSE);
|
|
|
|
if (!bKey && (iFlags & REPDRVR_FLAG_KEY))
|
|
{
|
|
hr = InsertClassKeys(pConn, dClassId, iNewPropId);
|
|
bKey = TRUE;
|
|
}
|
|
if (!bLocal && bKey)
|
|
bKey = FALSE;
|
|
if (bIsKey)
|
|
*bIsKey = bKey;
|
|
|
|
}
|
|
else
|
|
{
|
|
BOOL bInsert = TRUE;
|
|
if (iNewPropId)
|
|
bInsert = FALSE;
|
|
|
|
hr = InsertPropertyMap(pConn, iNewPropId, dClassId, StorageType, CIMType,
|
|
lpPropName, iFlags, bInsert);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (CIMType == CIM_REFERENCE)
|
|
{
|
|
if (dRefClassId)
|
|
hr = InsertReferenceProperties (pConn, dClassId, iNewPropId, dRefClassId, FALSE);
|
|
else
|
|
{
|
|
hr = DeleteReferenceProperties(pConn, iNewPropId, dClassId);
|
|
if (REPDRVR_FLAG_CLASSREFS & iFlags)
|
|
{
|
|
// Enumerate the class refs on this property.
|
|
|
|
IWbemQualifierSet *pQS = NULL;
|
|
hr = pObj->GetPropertyQualifierSet(lpPropName, &pQS);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
VARIANT vValue;
|
|
VariantInit(&vValue);
|
|
CReleaseMe r (pQS);
|
|
CClearMe c (&vValue);
|
|
|
|
hr = pQS->Get(L"ClassRef", 0, &vValue, NULL);
|
|
if (SUCCEEDED(hr) && vValue.vt == VT_BSTR+CIM_FLAG_ARRAY)
|
|
{
|
|
SAFEARRAY *psaArray = V_ARRAY(&vValue);
|
|
if (psaArray)
|
|
{
|
|
VARIANT vVal;
|
|
VariantInit(&vVal);
|
|
CClearMe c (&vVal);
|
|
long lLBound, lUBound;
|
|
SafeArrayGetLBound(psaArray, 1, &lLBound);
|
|
SafeArrayGetUBound(psaArray, 1, &lUBound);
|
|
|
|
lUBound -= lLBound;
|
|
lUBound += 1;
|
|
for (int i = 0; i < lUBound; i++)
|
|
{
|
|
hr = GetVariantFromArray(psaArray, i, VT_BSTR, vVal);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
SQL_ID dRefClass = 0;
|
|
hr = pCache->GetClassID(vVal.bstrVal, dScopeId, dRefClass);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = InsertReferenceProperties(pConn, dClassId, iNewPropId, dRefClass, TRUE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if ((iFlags & REPDRVR_FLAG_KEY))
|
|
{
|
|
hr = InsertClassKeys(pConn, dClassId, iNewPropId);
|
|
if (bIsKey)
|
|
*bIsKey = TRUE;
|
|
}
|
|
else if (bIsKey)
|
|
*bIsKey = FALSE;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
BOOL bLocal = FALSE;
|
|
if (!(iFlags & REPDRVR_FLAG_KEY) && pCache->IsKey(dClassId, iNewPropId, bLocal))
|
|
{
|
|
pCache->SetIsKey(dClassId, iNewPropId, FALSE);
|
|
hr = DeleteClassKeys(pConn, dClassId, iNewPropId);
|
|
if (bIsKey)
|
|
*bIsKey = FALSE;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::InsertBlobData
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::InsertBlobData (CSQLConnection *pConn, SQL_ID dClassId, SQL_ID dObjectId, DWORD iPropertyId,
|
|
BYTE *pImage, DWORD iPos, DWORD dwNumBytes)
|
|
{
|
|
return InsertClassImages (pConn, dObjectId, iPropertyId, iPos, pImage, dwNumBytes);
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::InsertPropertyBatch
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::InsertPropertyBatch (CSQLConnection *pConn, LPCWSTR lpObjectKey, LPCWSTR lpPath, LPCWSTR lpClassName,
|
|
SQL_ID dClassId, SQL_ID dScopeId, DWORD iInsertFlags, InsertPropValues *pVals, DWORD iNumVals, SQL_ID &dNewObjectId)
|
|
{
|
|
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
BOOL bExists = FALSE;
|
|
BOOL bDeleted = FALSE;
|
|
|
|
|
|
// Find existing ID, based on lpObjectKey.
|
|
// Verify insert/update flags
|
|
|
|
if (!dNewObjectId)
|
|
{
|
|
SQL_ID dTemp;
|
|
hr = GetObjectIdByPath(pConn, lpObjectKey, dNewObjectId, dTemp, NULL, &bDeleted);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
bExists = TRUE;
|
|
if ((!bDeleted) && iInsertFlags & WBEM_FLAG_CREATE_ONLY)
|
|
hr = WBEM_E_ALREADY_EXISTS;
|
|
else if (bDeleted && (iInsertFlags & WBEM_FLAG_UPDATE_ONLY))
|
|
hr = WBEM_E_INVALID_OBJECT;
|
|
else
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
else if (iInsertFlags & WBEM_FLAG_UPDATE_ONLY)
|
|
hr = WBEM_E_INVALID_OBJECT;
|
|
else
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
dNewObjectId = CRC64::GenerateHashValue(lpObjectKey);
|
|
}
|
|
else
|
|
bExists = TRUE;
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
BOOL bInsert = TRUE;
|
|
if (bExists)
|
|
bInsert = FALSE;
|
|
|
|
LPWSTR lpPath2 = StripQuotes((LPWSTR)lpPath);
|
|
CDeleteMe <wchar_t> d (lpPath2);
|
|
|
|
hr = InsertObjectMap(pConn, dNewObjectId, lpObjectKey, 0, lpPath2, dScopeId, 0, 0, dClassId, bInsert);
|
|
if (SUCCEEDED(hr) && bExists)
|
|
{
|
|
// Delete all qualifiers, since we will reinsert them all.
|
|
// (Guess we can't do this through accessors.)
|
|
|
|
hr = DeleteQualifiers(pConn, dNewObjectId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (iInsertFlags & WMIDB_HANDLE_TYPE_AUTODELETE)
|
|
hr = InsertAutoDelete(pConn, dNewObjectId);
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
hr = InsertBatch(pConn, dNewObjectId, dScopeId, dClassId, pVals, iNumVals);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::InsertBatch
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::InsertBatch (CSQLConnection *pConn, SQL_ID dObjectId, SQL_ID dScopeId, SQL_ID dClassId,
|
|
InsertQfrValues *pVals, DWORD iNumVals)
|
|
{
|
|
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
// Insert each property/qualifier/method/method parameter:
|
|
|
|
if (dClassId == CONTAINERASSOCID)
|
|
{
|
|
for (int i = 0; i < iNumVals; i++)
|
|
{
|
|
if (pVals[i].pRefKey != NULL)
|
|
{
|
|
SQL_ID dContaineeId = _wtoi64(pVals[i].pRefKey);
|
|
SQL_ID dContainerId = _wtoi64(pVals[i+1].pRefKey);
|
|
|
|
hr = InsertContainerObjs(pConn, dContainerId, dContaineeId);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < iNumVals; i++)
|
|
{
|
|
SQL_ID dRefID = 0, dRefClassID = 0;
|
|
BOOL bExisting = FALSE, bEx2 = FALSE;
|
|
IRowset *pIRowset = NULL;
|
|
InsertQfrValues *pVal = &pVals[i];
|
|
DWORD dwRows = 0;
|
|
LPWSTR lpVal = NULL;
|
|
BOOL bRefCount = FALSE;
|
|
LPWSTR sVal = NULL;
|
|
SQL_ID dVal = 0;
|
|
double rVal = 0;
|
|
bool bStoreTextAsImage = false;
|
|
BOOL bIsNull = FALSE;
|
|
|
|
switch(pVal->iStorageType)
|
|
{
|
|
case WMIDB_STORAGE_STRING:
|
|
|
|
if (pVal->pValue)
|
|
{
|
|
sVal = TruncateLongText(pVal->pValue, 127, bStoreTextAsImage, 127);
|
|
if (bStoreTextAsImage)
|
|
pVal->bLong = TRUE;
|
|
}
|
|
else
|
|
bIsNull = TRUE;
|
|
|
|
// Clean up any previously-created string data stored as images.
|
|
hr = DeleteClassImages(pConn, pVal->iPropID, dObjectId, pVal->iPos);
|
|
|
|
hr = InsertClassData_Internal (pConn, dObjectId, pVal->iPropID, pVal->iPos, pVal->iQfrID,
|
|
pVal->dClassId, sVal, 0, 0, pVal->iFlavor, pVal->iQfrID, 0, bIsNull);
|
|
|
|
if (SUCCEEDED(hr) && pVal->bIndexed)
|
|
{
|
|
hr = InsertIndexData (pConn, dObjectId, pVal->iPropID, pVal->iPos,
|
|
sVal, 0, 0, pVal->iStorageType);
|
|
}
|
|
|
|
delete sVal;
|
|
|
|
break;
|
|
|
|
case WMIDB_STORAGE_NUMERIC:
|
|
if (pVal->pValue)
|
|
dVal = _wtoi64(pVal->pValue);
|
|
else
|
|
bIsNull = TRUE;
|
|
|
|
hr = InsertClassData_Internal (pConn, dObjectId, pVal->iPropID, pVal->iPos, pVal->iQfrID,
|
|
pVal->dClassId, NULL, dVal, 0, pVal->iFlavor, pVal->iQfrID, 0, bIsNull);
|
|
if (SUCCEEDED(hr) && pVal->bIndexed)
|
|
{
|
|
hr = InsertIndexData (pConn, dObjectId, pVal->iPropID, pVal->iPos,
|
|
NULL, dVal, 0, pVal->iStorageType);
|
|
}
|
|
break;
|
|
case WMIDB_STORAGE_REAL:
|
|
if (pVal->pValue)
|
|
rVal = wcstod(pVal->pValue, &lpVal);
|
|
else
|
|
bIsNull = TRUE;
|
|
hr = InsertClassData_Internal (pConn, dObjectId, pVal->iPropID, pVal->iPos, pVal->iQfrID,
|
|
pVal->dClassId, NULL, 0, rVal, pVal->iFlavor, pVal->iQfrID, 0, bIsNull);
|
|
if (SUCCEEDED(hr) && pVal->bIndexed)
|
|
{
|
|
hr = InsertIndexData (pConn, dObjectId, pVal->iPropID, pVal->iPos,
|
|
NULL, rVal, 0, pVal->iStorageType);
|
|
}
|
|
break;
|
|
case WMIDB_STORAGE_REFERENCE:
|
|
|
|
// * If this is a reference, we need to get the ID from the key string.
|
|
// If this object does not exist, we need to insert a bogus row.
|
|
// Bump up the ref count.
|
|
// If this is an update, decrement the ref count on previous row
|
|
// If previous row now has zero ref count, remove it.
|
|
|
|
dRefID = _wtoi64(pVal->pRefKey);
|
|
{
|
|
IRowset *pRowset = NULL;
|
|
IAccessor *pAccessor = NULL;
|
|
HACCESSOR hAcc = NULL;
|
|
CLASSDATA cd;
|
|
BOOL bOldRow = FALSE;
|
|
|
|
hr = GetFirst_ClassData(pConn, dObjectId, cd,pVal->iPropID);
|
|
while (hr == WBEM_S_NO_ERROR)
|
|
{
|
|
if (pVal->iPos == cd.iArrayPos &&
|
|
pVal->iQfrID == cd.iQfrPos)
|
|
{
|
|
bExisting = TRUE;
|
|
SQL_ID dOldRefID = cd.dRefId;
|
|
if (dRefID != dOldRefID)
|
|
{
|
|
PROPERTYMAP pm;
|
|
|
|
hr = GetFirst_PropertyMap(pConn, pVal->iPropID, pm);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (pm.iCIMTypeId == CIM_OBJECT)
|
|
hr = DeleteObjectMap(pConn, dOldRefID, TRUE);
|
|
else
|
|
{
|
|
OBJECTMAP om;
|
|
hr = GetFirst_ObjectMap(pConn, dOldRefID, om);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
bOldRow = TRUE;
|
|
bRefCount = TRUE;
|
|
if (om.iRefCount)
|
|
om.iRefCount--;
|
|
hr = UpdateObjectMap(pConn, om);
|
|
om.Clear();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
bOldRow = TRUE;
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
hr = GetNext_ClassData(pConn, cd, pVal->iPropID);
|
|
if (cd.dObjectId != dObjectId)
|
|
{
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
}
|
|
hr = 0;
|
|
if (!bOldRow)
|
|
bRefCount = TRUE;
|
|
}
|
|
|
|
if (pVal->pValue)
|
|
{
|
|
lpVal = StripQuotes(pVal->pValue);
|
|
|
|
ObjectExists(pConn, dRefID, bEx2, &dRefClassID, NULL, TRUE);
|
|
if (!bEx2)
|
|
{
|
|
// We need to insert this row and get the new ID.
|
|
LPWSTR lpKey = GetKeyString(pVal->pValue);
|
|
CDeleteMe <wchar_t> d (lpKey);
|
|
|
|
hr = InsertObjectMap(pConn, dRefID, lpKey, 2, lpVal, dObjectId, 1, 1, 0, TRUE);
|
|
}
|
|
else if (bRefCount)
|
|
{
|
|
IRowset *pRowset = NULL;
|
|
IAccessor *pAccessor = NULL;
|
|
HACCESSOR hAcc = NULL;
|
|
|
|
OBJECTMAP om;
|
|
hr = GetFirst_ObjectMap(pConn, dRefID, om);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
om.iRefCount++;
|
|
hr = UpdateObjectMap(pConn, om);
|
|
om.Clear();
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// update/insert the new row
|
|
|
|
sVal = TruncateLongText(pVal->pValue, 127, bStoreTextAsImage, 127);
|
|
if (bStoreTextAsImage)
|
|
pVal->bLong = TRUE;
|
|
|
|
hr = InsertClassData_Internal (pConn, dObjectId, pVal->iPropID, pVal->iPos, pVal->iQfrID,
|
|
pVal->dClassId, sVal, 0, 0, pVal->iFlavor, dRefID, dRefClassID, FALSE);
|
|
|
|
if (SUCCEEDED(hr) && pVal->bIndexed)
|
|
{
|
|
DWORD dwRows = 0;
|
|
hr = InsertIndexData (pConn, dObjectId, pVal->iPropID, pVal->iPos,
|
|
sVal, dRefID, 0, pVal->iStorageType);
|
|
}
|
|
|
|
delete sVal;
|
|
}
|
|
delete lpVal;
|
|
}
|
|
|
|
break;
|
|
|
|
// This should never be hit.
|
|
default:
|
|
pVal->bLong = TRUE;
|
|
continue;
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
break;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// If our text was too long, we need to store it as an image.
|
|
for (i = 0; i < iNumVals; i++)
|
|
{
|
|
if (pVals[i].bLong)
|
|
{
|
|
if (pVals[i].iStorageType == WMIDB_STORAGE_STRING ||
|
|
pVals[i].iStorageType == WMIDB_STORAGE_REFERENCE)
|
|
{
|
|
LPWSTR lpTemp = StripQuotes2 (pVals[i].pValue);
|
|
CDeleteMe <wchar_t> d (lpTemp);
|
|
hr = InsertBlobData (pConn, dClassId, dObjectId, pVals[i].iPropID, (BYTE *)lpTemp, 0, wcslen(lpTemp)*2+2);
|
|
}
|
|
else if (pVals[i].pValue == NULL) // This is a null blob!
|
|
hr = DeleteClassImages(pConn, pVals[i].iPropID, dObjectId);
|
|
else
|
|
{
|
|
ERRORTRACE((LOG_WBEMCORE, "Invalid argument in InsertBatch (Obj %I64d, Class %I64d, Prop %ld)", \
|
|
dObjectId, dClassId, pVals[i].iPropID));
|
|
}
|
|
}
|
|
delete pVals[i].pValue;
|
|
delete pVals[i].pRefKey;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::ObjectExists
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::ObjectExists (CSQLConnection *pConn, SQL_ID dId, BOOL &bExists, SQL_ID *_dClassId,
|
|
SQL_ID *_dScopeId, BOOL bDeletedOK)
|
|
{
|
|
|
|
SQL_ID dClassId, dScopeId;
|
|
BOOL bDeleted = FALSE;
|
|
OBJECTMAP oj;
|
|
|
|
HRESULT hr = GetFirst_ObjectMap(pConn, dId, oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
bExists = TRUE;
|
|
if (oj.iObjectState == 2)
|
|
{
|
|
if (!bDeletedOK)
|
|
bExists = FALSE;
|
|
}
|
|
|
|
if (bExists)
|
|
{
|
|
if (_dClassId) *_dClassId = oj.dClassId;
|
|
if (_dScopeId) *_dScopeId = oj.dObjectScopeId;
|
|
}
|
|
oj.Clear();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::RenameSubscopes
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::RenameSubscopes (CSQLConnection *pConn, LPWSTR lpOldPath, LPWSTR lpOldKey, LPWSTR lpNewPath, LPWSTR lpNewKey)
|
|
{
|
|
HRESULT hr = 0;
|
|
|
|
OBJECTMAP om;
|
|
|
|
// Enumerate all objects, and rename any that begin with the old path string.
|
|
|
|
hr = SetupObjectMapAccessor(pConn);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
|
|
int iOldPathLen = wcslen(lpOldPath);
|
|
int iOldKeyLen = wcslen(lpOldKey);
|
|
|
|
SQL_ID OldId = CRC64::GenerateHashValue(lpOldKey);
|
|
SQL_ID NewId = CRC64::GenerateHashValue(lpNewKey);
|
|
|
|
hr = OpenEnum_ObjectMap(pConn, om);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (!_wcsnicmp(om.sObjectPath, lpOldPath, iOldPathLen))
|
|
{
|
|
// Path = @NewPath + substring(ObjectPath, @OldPathLen+1, (datalength(ObjectPath)/2)- @OldPathLen),
|
|
// Key = substring(ObjectKey, 1, charindex(@OldKey, ObjectKey)-1) +@NewKey
|
|
|
|
LPWSTR lpTemp = NULL;
|
|
if (wcslen(om.sObjectPath) > iOldPathLen)
|
|
{
|
|
lpTemp = &om.sObjectPath[iOldPathLen];
|
|
LPWSTR lpNew = new wchar_t [wcslen(om.sObjectPath) + wcslen(lpNewPath)+1];
|
|
CDeleteMe <wchar_t> d(lpNew);
|
|
if (lpNew)
|
|
{
|
|
wcscpy(lpNew, lpNewPath);
|
|
wcscat(lpNew, lpTemp);
|
|
om.sObjectPath = SysAllocString(lpNew);
|
|
|
|
LPWSTR lpNew2 = new wchar_t [wcslen(om.sObjectKey) + wcslen(lpNewKey) + 1];
|
|
if (lpNew2 && om.sObjectPath)
|
|
{
|
|
lpTemp = om.sObjectKey;
|
|
lpTemp[iOldKeyLen] = L'\0';
|
|
wcscpy(lpNew2, lpTemp);
|
|
wcscat(lpNew2, lpNewKey);
|
|
om.sObjectKey = SysAllocString(lpNew2);
|
|
|
|
if (om.dObjectScopeId == OldId)
|
|
om.dObjectScopeId = NewId;
|
|
if (om.dClassId == OldId)
|
|
om.dClassId = NewId;
|
|
if (om.dObjectId == OldId)
|
|
om.dObjectId = NewId;
|
|
|
|
hr = UpdateObjectMap(pConn, om);
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
om.sObjectPath = SysAllocString(lpNewPath);
|
|
om.sObjectKey = SysAllocString(lpNewKey);
|
|
|
|
if (om.sObjectPath && om.sObjectKey)
|
|
hr = UpdateObjectMap(pConn, om);
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
else if (om.sObjectPath[0] > lpOldPath[0])
|
|
om.Clear();
|
|
hr = GetNext_ObjectMap(pConn, om);
|
|
}
|
|
|
|
// FIXME: We don't currently update ClassData and IndexRefData!
|
|
// IF this is a class, we don't update the ClassMap and PropertyMap!!!
|
|
|
|
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::GetSecurityDescriptor
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::GetSecurityDescriptor(CSQLConnection *pConn, SQL_ID dObjectId,
|
|
PNTSECURITY_DESCRIPTOR * ppSD, DWORD &dwBuffLen,
|
|
DWORD dwFlags)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// If this is a class , get the security for __ClassSecurity (WMIDB_SECURITY_FLAG_CLASS)
|
|
// or __Instances container (WMIDB_SECURITY_FLAG_INSTANCE)
|
|
// If this is a namespace, get the security for __ThisNamespace
|
|
// Otherwise, get it off the object itself.
|
|
// Make sure its a valid security descriptor, before we
|
|
// return anything.
|
|
|
|
*ppSD = NULL;
|
|
|
|
PNTSECURITY_DESCRIPTOR pSD = NULL;
|
|
dwBuffLen = 0;
|
|
OBJECTMAP oj;
|
|
CLASSMAP cm;
|
|
|
|
SQL_ID dID = 0;
|
|
|
|
hr = GetFirst_ClassMap(pConn, dObjectId, cm);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
LPWSTR lpRetrievalName = NULL;
|
|
SQL_ID dScopeId = oj.dObjectScopeId;
|
|
int iSize = 0;
|
|
oj.Clear();
|
|
|
|
// We need to generate the path of the class
|
|
|
|
if (dwFlags == WMIDB_SECURITY_FLAG_INSTANCE)
|
|
{
|
|
if (dScopeId)
|
|
{
|
|
hr = GetFirst_ObjectMap(pConn, dScopeId, oj);
|
|
iSize = wcslen(oj.sObjectPath) + wcslen(cm.sClassName) + 128;
|
|
}
|
|
else
|
|
iSize = wcslen(cm.sClassName) + 128;
|
|
|
|
lpRetrievalName = new wchar_t [iSize];
|
|
CDeleteMe <wchar_t> d (lpRetrievalName);
|
|
if (lpRetrievalName)
|
|
{
|
|
if (dScopeId)
|
|
swprintf(lpRetrievalName, L"%s:__ClassInstancesSecurity=\"%s\"", oj.sObjectPath, cm.sClassName);
|
|
else
|
|
swprintf(lpRetrievalName, L"__ClassInstancesSecurity=\"%s\"", cm.sClassName);
|
|
|
|
LPWSTR lpKey = GetKeyString(lpRetrievalName);
|
|
CDeleteMe <wchar_t> d2 (lpKey);
|
|
if (lpKey)
|
|
{
|
|
dID = CRC64::GenerateHashValue(lpKey);
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
}
|
|
else
|
|
{
|
|
// Get the __ClassSecurity object
|
|
|
|
if (dScopeId)
|
|
{
|
|
hr = GetFirst_ObjectMap(pConn, dScopeId, oj);
|
|
iSize = wcslen(oj.sObjectPath) + wcslen(cm.sClassName) + 128;
|
|
}
|
|
else
|
|
iSize = wcslen(cm.sClassName) + 128;
|
|
|
|
lpRetrievalName = new wchar_t [iSize];
|
|
CDeleteMe <wchar_t> d (lpRetrievalName);
|
|
if (lpRetrievalName)
|
|
{
|
|
if (dScopeId)
|
|
swprintf(lpRetrievalName, L"%s:__ClassSecurity=\"%s\"", oj.sObjectPath, cm.sClassName);
|
|
else
|
|
swprintf(lpRetrievalName, L"__ClassSecurity=\"%s\"", cm.sClassName);
|
|
|
|
LPWSTR lpKey = GetKeyString(lpRetrievalName);
|
|
CDeleteMe <wchar_t> d2 (lpKey);
|
|
if (lpKey)
|
|
{
|
|
dID = CRC64::GenerateHashValue(lpKey);
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
}
|
|
cm.Clear();
|
|
oj.Clear();
|
|
}
|
|
else
|
|
{
|
|
// Get the object itself.
|
|
hr = WBEM_S_NO_ERROR;
|
|
dID = dObjectId;
|
|
oj.Clear();
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CLASSIMAGES ci;
|
|
BOOL bFound = FALSE;
|
|
|
|
hr = GetFirst_ClassImages(pConn, dID, ci);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
PROPERTYMAP pm;
|
|
hr = GetFirst_PropertyMap(pConn, ci.iPropertyId, pm);
|
|
if (SUCCEEDED(hr) && (!_wcsicmp(pm.sPropertyName, L"__SECURITY_DESCRIPTOR")))
|
|
{
|
|
pSD = ci.pBuffer;
|
|
bFound = TRUE;
|
|
if (pSD != NULL)
|
|
{
|
|
if (IsValidSecurityDescriptor(pSD))
|
|
{
|
|
// Make a copy of it.
|
|
pSD = (PNTSECURITY_DESCRIPTOR)CWin32DefaultArena::WbemMemAlloc(ci.dwBufferLen);
|
|
|
|
ZeroMemory(pSD, ci.dwBufferLen);
|
|
memcpy(pSD, ci.pBuffer, ci.dwBufferLen);
|
|
*ppSD = pSD;
|
|
dwBuffLen = ci.dwBufferLen;
|
|
}
|
|
}
|
|
}
|
|
pm.Clear();
|
|
|
|
if (bFound)
|
|
break;
|
|
|
|
hr = GetNext_ClassImages(pConn, ci);
|
|
}
|
|
ci.Clear();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::EnumerateSecuredChildren
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::EnumerateSecuredChildren(CSQLConnection *pConn, CSchemaCache *pCache, SQL_ID dObjectId, SQL_ID dClassId, SQL_ID dScopeId,
|
|
SQLIDs &ObjIds, SQLIDs &ClassIds, SQLIDs &ScopeIds)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// If __Classes instance, we need to enumerate all instances of __ClassSecurity
|
|
// If this is a __ClassSecurity instance, we need to enumerate all instances
|
|
// of __ClassSecurity for all subclasses
|
|
// If this is a __ClassInstancesSecurity instance, we need to enumerate all
|
|
// instances of this class
|
|
// If this is a namespace (__ThisNamespace) or scope, we need all subscoped objects
|
|
|
|
SQL_ID dClassSecurityId = CLASSSECURITYID;
|
|
SQL_ID dClassesId = CLASSESID;
|
|
SQL_ID dClassInstSecurityId = CLASSINSTSECID;
|
|
SQL_ID dThisNamespaceId = THISNAMESPACEID;
|
|
|
|
DWORD dwSecPropID = 0;
|
|
|
|
hr = pCache->GetPropertyID(L"__SECURITY_DESCRIPTOR", 1, 0, REPDRVR_IGNORE_CIMTYPE, dwSecPropID);
|
|
|
|
if (dClassId == dClassesId)
|
|
{
|
|
// All classes in this namespace.
|
|
OBJECTMAP oj;
|
|
hr = GetFirst_ObjectMapByClass(pConn, dClassSecurityId, oj);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (oj.dObjectScopeId == dScopeId)
|
|
{
|
|
// This is pointing to some class, we don't care
|
|
// which one.
|
|
|
|
CLASSIMAGES ci;
|
|
hr = GetFirst_ClassImages(pConn, oj.dObjectId, ci);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (ci.iPropertyId == dwSecPropID)
|
|
{
|
|
ObjIds.push_back(oj.dObjectId);
|
|
ClassIds.push_back(oj.dClassId);
|
|
ScopeIds.push_back(oj.dObjectScopeId);
|
|
ci.Clear();
|
|
break;
|
|
}
|
|
hr = GetNext_ClassImages(pConn, ci);
|
|
}
|
|
}
|
|
|
|
hr = GetNext_ObjectMap(pConn, oj);
|
|
}
|
|
}
|
|
else if (dClassId == dClassSecurityId)
|
|
{
|
|
// All __ClassSecurity for subclasses of this class
|
|
|
|
// Get the class name
|
|
// Get the ID for the class name in this namespace
|
|
// Enumerate subclasses
|
|
// Format the name
|
|
// Generate the Object ID
|
|
|
|
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
else if (dClassId == dClassInstSecurityId)
|
|
{
|
|
// All instances of this class and subclasses.
|
|
|
|
// Get the class name
|
|
// Get the ID for the class name in this namespace
|
|
// Enumerate subclasses
|
|
// Enumerate all instances of each class
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
else
|
|
{
|
|
// Regular instance. Enumerate all objects
|
|
// scoped to this .
|
|
|
|
SQL_ID dThis = dObjectId;
|
|
|
|
if (dClassId == dThisNamespaceId)
|
|
dThis = dScopeId;
|
|
|
|
SQL_ID * pScopes = NULL;
|
|
int iNumScopes = 0;
|
|
|
|
hr = pCache->GetSubScopes(dThis, &pScopes, iNumScopes);
|
|
for (int i = 0; i < iNumScopes; i++)
|
|
{
|
|
OBJECTMAP oj;
|
|
hr = GetFirst_ObjectMapByScope(pConn, pScopes[i], oj);
|
|
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
CLASSIMAGES ci;
|
|
hr = GetFirst_ClassImages(pConn, oj.dObjectId, ci);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (ci.iPropertyId == dwSecPropID)
|
|
{
|
|
ObjIds.push_back(oj.dObjectId);
|
|
ClassIds.push_back(oj.dClassId);
|
|
ScopeIds.push_back(oj.dObjectScopeId);
|
|
ci.Clear();
|
|
break;
|
|
}
|
|
hr = GetNext_ClassImages(pConn, ci);
|
|
}
|
|
|
|
hr = GetNext_ObjectMap(pConn, oj);
|
|
}
|
|
}
|
|
delete pScopes;
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::EnumerateSubScopes
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::EnumerateSubScopes (CSQLConnection *pConn, SQL_ID dScopeId)
|
|
{
|
|
return E_NOTIMPL;
|
|
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::InsertScopeMap
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::InsertScopeMap (CSQLConnection *pConn, SQL_ID dScopeId, LPCWSTR lpScopePath, SQL_ID dParentId)
|
|
{
|
|
HRESULT hr = InsertScopeMap_Internal(pConn, dScopeId, lpScopePath, dParentId);
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::InsertUncommittedEvent
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::InsertUncommittedEvent (CSQLConnection *pConn, LPCWSTR lpGUID, LPWSTR lpNamespace,
|
|
LPWSTR lpClassName, IWbemClassObject *pOldObj,
|
|
IWbemClassObject *pNewObj, CSchemaCache *pCache)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
static int iNumProps = 4;
|
|
InsertPropValues *pVals = new InsertPropValues[iNumProps];
|
|
|
|
if (!pVals)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
CDeleteMe <InsertPropValues> d (pVals);
|
|
LPWSTR lpObjectKey = NULL, lpPath = NULL;
|
|
SQL_ID dScopeId = 1;
|
|
SQL_ID dObjectId = 0;
|
|
SQL_ID dKeyhole = 0;
|
|
static SQL_ID dClassId = 0;
|
|
static DWORD dwPropId1 = 0, dwPropId2 = 0, dwPropId3 = 0, dwPropId4 = 0, dwPropId5 = 0, dwPropId6 = 0, dwPropId7 = 0;
|
|
|
|
if (!dwPropId1)
|
|
{
|
|
hr = pCache->GetClassID(L"__UncommittedEvent", 1, dClassId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pCache->GetPropertyID(L"EventID", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId1);
|
|
hr = pCache->GetPropertyID(L"TransactionGUID", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId2);
|
|
hr = pCache->GetPropertyID(L"NamespaceName", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId3);
|
|
hr = pCache->GetPropertyID(L"ClassName", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId4);
|
|
hr = pCache->GetPropertyID(L"OldObject", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId5);
|
|
hr = pCache->GetPropertyID(L"NewObject", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId6);
|
|
hr = pCache->GetPropertyID(L"Transacted", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId7);
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = GetNextKeyhole(pConn, dwPropId1, dKeyhole);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
LPWSTR lpKey = new wchar_t [40];
|
|
lpObjectKey = new wchar_t [100];
|
|
lpPath = new wchar_t [100];
|
|
|
|
CDeleteMe <wchar_t> d2 (lpKey), d3 (lpObjectKey), d4 (lpPath);
|
|
|
|
if (!lpKey || !lpObjectKey || !lpPath)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
swprintf(lpKey, L"%ld", dKeyhole);
|
|
swprintf(lpObjectKey, L"%ld?__UncommittedEvent", dKeyhole);
|
|
swprintf(lpObjectKey, L"__UncommittedEvent=%ld", dKeyhole);
|
|
|
|
pVals[0].iPropID = dwPropId1;
|
|
pVals[0].bIndexed = TRUE;
|
|
pVals[0].iStorageType = WMIDB_STORAGE_NUMERIC;
|
|
pVals[0].dClassId = dClassId;
|
|
pVals[0].pValue = lpKey;
|
|
pVals[1].iPropID = dwPropId2;
|
|
pVals[1].bIndexed = TRUE;
|
|
pVals[1].iStorageType = WMIDB_STORAGE_STRING;
|
|
pVals[1].dClassId = dClassId;
|
|
pVals[1].pValue = (LPWSTR)lpGUID;
|
|
pVals[2].iPropID = dwPropId3;
|
|
pVals[2].iStorageType = WMIDB_STORAGE_STRING;
|
|
pVals[2].dClassId = dClassId;
|
|
pVals[2].pValue = lpClassName;
|
|
pVals[3].iPropID = dwPropId4;
|
|
pVals[3].iStorageType = WMIDB_STORAGE_STRING;
|
|
pVals[3].dClassId = dClassId;
|
|
pVals[3].pValue = (LPWSTR)lpNamespace;
|
|
pVals[4].iPropID = dwPropId6;
|
|
pVals[4].iStorageType = WMIDB_STORAGE_NUMERIC;
|
|
pVals[4].dClassId = dClassId;
|
|
pVals[4].pValue = new wchar_t [1];
|
|
if (!pVals[4].pValue)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
wcscpy(pVals[4].pValue, L"1");
|
|
|
|
hr = InsertPropertyBatch (pConn, lpObjectKey, lpPath, lpClassName,
|
|
dClassId, dScopeId, 0, pVals, iNumProps, dObjectId);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (pOldObj)
|
|
{
|
|
_IWmiObject *pInt = NULL;
|
|
hr = pOldObj->QueryInterface(IID__IWmiObject, (void **)&pInt);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD dwLen = 0;
|
|
pInt->GetObjectMemory(NULL, 0, &dwLen);
|
|
BYTE *pBuff = new BYTE [dwLen];
|
|
if (pBuff)
|
|
{
|
|
CDeleteMe <BYTE> d (pBuff);
|
|
DWORD dwLen1;
|
|
hr = pInt->GetObjectMemory(pBuff, dwLen, &dwLen1);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = CSQLExecProcedure::InsertBlobData(pConn, dClassId, dObjectId,
|
|
dwPropId4, pBuff, 0, dwLen);
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
pInt->Release();
|
|
}
|
|
}
|
|
|
|
if (pNewObj)
|
|
{
|
|
_IWmiObject *pInt = NULL;
|
|
hr = pNewObj->QueryInterface(IID__IWmiObject, (void **)&pInt);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD dwLen = 0;
|
|
pInt->GetObjectMemory(NULL, 0, &dwLen);
|
|
BYTE *pBuff = new BYTE [dwLen];
|
|
if (pBuff)
|
|
{
|
|
CDeleteMe <BYTE> d (pBuff);
|
|
DWORD dwLen1;
|
|
hr = pInt->GetObjectMemory(pBuff, dwLen, &dwLen1);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = CSQLExecProcedure::InsertBlobData(pConn, dClassId, dObjectId,
|
|
dwPropId4, pBuff, 0, dwLen);
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
pInt->Release();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::DeleteUncommittedEvents
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::DeleteUncommittedEvents (CSQLConnection *pConn, LPCWSTR lpGUID,
|
|
CSchemaCache *pCache, CObjectCache *pObjCache)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Delete all events by GUID
|
|
// The simplest thing to do is to scan IndexStringData
|
|
// for this GUID and delete each object that way
|
|
|
|
INDEXDATA id;
|
|
JET_TABLEID tableid;
|
|
DWORD dwPos;
|
|
SQLIDs ids;
|
|
|
|
SQL_ID dClassId;
|
|
hr = pCache->GetClassID(L"__UncommittedEvent", 1, dClassId);
|
|
|
|
// Find all objects that match this GUID...
|
|
|
|
hr = GetFirst_IndexDataString(pConn, (LPWSTR)lpGUID, id, tableid, dwPos);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
ids.push_back(id.dObjectId);
|
|
|
|
// Clean up object cache for each event
|
|
|
|
pObjCache->DeleteObject(id.dObjectId);
|
|
|
|
hr = GetNext_IndexData(pConn, tableid, dwPos, id);
|
|
}
|
|
|
|
// Delete 'em...
|
|
|
|
for (int i = 0; i < ids.size(); i++)
|
|
{
|
|
OBJECTMAP oj;
|
|
hr = GetFirst_ObjectMap(pConn, ids.at(i), oj);
|
|
if (oj.dClassId == dClassId)
|
|
{
|
|
oj.Clear();
|
|
hr = DeleteObjectMap(pConn, ids.at(i));
|
|
if (FAILED(hr))
|
|
break;
|
|
}
|
|
oj.Clear();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::CommitEvents
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::CommitEvents(CSQLConnection *pConn,_IWmiCoreServices *pESS,
|
|
LPCWSTR lpRoot, LPCWSTR lpGUID, CSchemaCache *pCache, CObjectCache *pObjCache)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// Enumerate event objects,
|
|
// fire an event for each (distinguishing classes, instances, and namespaces,
|
|
// and creation, deletion, modification)
|
|
// Delete each event.
|
|
|
|
INDEXDATA id;
|
|
JET_TABLEID tableid;
|
|
DWORD dwPos;
|
|
SQLIDs ids;
|
|
SQL_ID dClassId;
|
|
hr = pCache->GetClassID(L"__UncommittedEvent", 1, dClassId);
|
|
|
|
// Find all objects that match this GUID...
|
|
|
|
hr = GetFirst_IndexDataString(pConn, (LPWSTR)lpGUID, id, tableid, dwPos);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
ids.push_back(id.dObjectId);
|
|
|
|
// Clean up object cache for each event
|
|
|
|
pObjCache->DeleteObject(id.dObjectId);
|
|
|
|
hr = GetNext_IndexData(pConn, tableid, dwPos, id);
|
|
}
|
|
|
|
// Fire an event, and delete the object...
|
|
|
|
for (int i = 0; i < ids.size(); i++)
|
|
{
|
|
long lType = 0;
|
|
_bstr_t sNamespace;
|
|
_bstr_t sClassName;
|
|
DWORD dwNumObjs = 1;
|
|
_IWmiObject **pObjs = NULL;
|
|
_IWmiObject *pOldObj = NULL;
|
|
_IWmiObject *pNewObj = NULL;
|
|
LPWSTR lpNewNs = NULL;
|
|
|
|
OBJECTMAP oj;
|
|
hr = GetFirst_ObjectMap(pConn, ids.at(i), oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (oj.dClassId != dClassId)
|
|
{
|
|
oj.Clear();
|
|
continue;
|
|
}
|
|
|
|
// Extract the data from the tables.
|
|
// OldObject, NewObject, ClassName and NamespaceName
|
|
// =================================================
|
|
|
|
static DWORD dwPropId1 = 0, dwPropId2 = 0, dwPropId3 = 0, dwPropId4 = 0;
|
|
|
|
if (!dwPropId1)
|
|
{
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pCache->GetPropertyID(L"NamespaceName", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId1);
|
|
hr = pCache->GetPropertyID(L"ClassName", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId2);
|
|
hr = pCache->GetPropertyID(L"OldObject", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId3);
|
|
hr = pCache->GetPropertyID(L"NewObject", dClassId, 0, REPDRVR_IGNORE_CIMTYPE, dwPropId4);
|
|
}
|
|
}
|
|
|
|
CLASSDATA cd;
|
|
hr = GetFirst_ClassData(pConn, ids.at(i), cd, dwPropId1);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
sNamespace = cd.sPropertyStringValue;
|
|
}
|
|
cd.Clear();
|
|
hr = GetFirst_ClassData(pConn, ids.at(i), cd, dwPropId2);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
sClassName = cd.sPropertyStringValue;
|
|
}
|
|
cd.Clear();
|
|
|
|
CLASSIMAGES ci;
|
|
hr = GetFirst_ClassImages(pConn, ids.at(i), ci);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (ci.iPropertyId == dwPropId3)
|
|
ConvertBlobToObject(NULL, ci.pBuffer, ci.dwBufferLen, &pOldObj);
|
|
else if (ci.iPropertyId == dwPropId4)
|
|
ConvertBlobToObject(NULL, ci.pBuffer, ci.dwBufferLen, &pNewObj);
|
|
|
|
hr = GetNext_ClassImages(pConn, ci);
|
|
}
|
|
ci.Clear();
|
|
|
|
// Namespace must be formatted with \\.\lpRoot\...
|
|
// Unless the namespace is root, and then we
|
|
// have to strip off the beginning...
|
|
// ===============================================
|
|
|
|
lpNewNs = new wchar_t [wcslen(sNamespace) + 50];
|
|
if (lpNewNs)
|
|
{
|
|
swprintf(lpNewNs, L"\\\\.\\%s\\%s", lpRoot, (LPCWSTR)sNamespace);
|
|
}
|
|
}
|
|
|
|
CDeleteMe <wchar_t> d4 (lpNewNs);
|
|
|
|
// Determine what type of event this is:
|
|
// Namespace | Class | Instance
|
|
// Creation | Modification | Deletion
|
|
// =====================================
|
|
|
|
if (!pNewObj && pOldObj)
|
|
{
|
|
pObjs = new _IWmiObject * [dwNumObjs];
|
|
if (pObjs)
|
|
{
|
|
pObjs[0] = pOldObj;
|
|
|
|
LPWSTR lpGenus = GetPropertyVal(L"__Genus", pOldObj);
|
|
CDeleteMe <wchar_t> d (lpGenus);
|
|
|
|
if (!wcscmp(lpGenus, L"1"))
|
|
lType = WBEM_EVENTTYPE_ClassDeletion;
|
|
else
|
|
{
|
|
if (IsDerivedFrom(pOldObj, L"__Namespace"))
|
|
lType = WBEM_EVENTTYPE_NamespaceDeletion;
|
|
else
|
|
lType = WBEM_EVENTTYPE_InstanceDeletion;
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else if (!pOldObj && pNewObj)
|
|
{
|
|
pObjs = new _IWmiObject *[dwNumObjs];
|
|
if (pObjs)
|
|
{
|
|
pObjs[0] = pNewObj;
|
|
|
|
LPWSTR lpGenus = GetPropertyVal(L"__Genus", pNewObj);
|
|
CDeleteMe <wchar_t> d (lpGenus);
|
|
|
|
if (!wcscmp(lpGenus, L"1"))
|
|
lType = WBEM_EVENTTYPE_ClassCreation;
|
|
else
|
|
{
|
|
if (IsDerivedFrom(pNewObj, L"__Namespace"))
|
|
lType = WBEM_EVENTTYPE_NamespaceCreation;
|
|
else
|
|
lType = WBEM_EVENTTYPE_InstanceCreation;
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
dwNumObjs = 2;
|
|
pObjs = new _IWmiObject *[dwNumObjs];
|
|
if (pObjs)
|
|
{
|
|
pObjs[0] = pOldObj;
|
|
pObjs[1] = pNewObj;
|
|
|
|
LPWSTR lpGenus = GetPropertyVal(L"__Genus", pNewObj);
|
|
CDeleteMe <wchar_t> d (lpGenus);
|
|
|
|
if (!wcscmp(lpGenus, L"1"))
|
|
lType = WBEM_EVENTTYPE_ClassModification;
|
|
else
|
|
{
|
|
if (IsDerivedFrom(pOldObj, L"__Namespace"))
|
|
lType = WBEM_EVENTTYPE_NamespaceModification;
|
|
else
|
|
lType = WBEM_EVENTTYPE_InstanceModification;
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
// Deliver the event...
|
|
// ====================
|
|
|
|
pESS->DeliverIntrinsicEvent(lpNewNs, lType, NULL,
|
|
sClassName, lpGUID, dwNumObjs, pObjs);
|
|
|
|
delete pObjs;
|
|
if (pOldObj)
|
|
pOldObj->Release();
|
|
if (pNewObj)
|
|
pNewObj->Release();
|
|
|
|
oj.Clear();
|
|
|
|
hr = DeleteObjectMap(pConn, ids.at(i));
|
|
if (FAILED(hr))
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CSQLExecProcedure::UpdateClassBlob
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CSQLExecProcedure::UpdateClassBlob (CSQLConnection *pConn, SQL_ID dClassId, _IWmiObject *pObj)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
BYTE buff[128];
|
|
DWORD dwLen = 0;
|
|
hr = pObj->Unmerge(0, 128, &dwLen, &buff);
|
|
|
|
if (dwLen > 0)
|
|
{
|
|
BYTE *pBuff = new BYTE [dwLen];
|
|
if (pBuff)
|
|
{
|
|
CDeleteMe <BYTE> r2 (pBuff);
|
|
DWORD dwLen1;
|
|
hr = pObj->Unmerge(0, dwLen, &dwLen1, pBuff);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CLASSMAP cd;
|
|
hr = GetFirst_ClassMap(pConn, dClassId, cd);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
delete cd.pClassBuffer;
|
|
cd.pClassBuffer = pBuff;
|
|
cd.dwBufferLen = dwLen;
|
|
|
|
hr = UpdateClassMap(pConn, cd);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::LoadSchemaCache
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CWmiDbSession::LoadSchemaCache ()
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
// This needs to load the cache with all class, property,
|
|
// and namespace data. We are going to call three straight
|
|
// select queries and grab the columns.
|
|
// ==========================================================
|
|
|
|
DWORD dwNumRows;
|
|
|
|
CSQLConnection *pConn = NULL;
|
|
|
|
if (m_pController)
|
|
hr = GetSQLCache()->GetConnection(&pConn);
|
|
|
|
if (SUCCEEDED(hr) && pConn)
|
|
{
|
|
// Enumerate scopes.
|
|
// =================
|
|
|
|
SCOPEMAP sm;
|
|
OBJECTMAP oj;
|
|
CLASSIMAGES ci;
|
|
DWORD dwSecurity;
|
|
|
|
hr = OpenEnum_ScopeMap(pConn, sm);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
hr = GetFirst_ObjectMap(pConn, sm.dObjectId, oj);
|
|
|
|
hr = GetSchemaCache()->AddNamespace
|
|
(sm.sScopePath, sm.sScopePath, sm.dObjectId, sm.dParentId, oj.dClassId);
|
|
|
|
oj.Clear();
|
|
|
|
if (FAILED(hr))
|
|
break;
|
|
|
|
hr = GetNext_ScopeMap(pConn, sm);
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
// Enumerate system classes.
|
|
|
|
if (FAILED(LoadClassInfo(pConn, L"meta_class", 0, FALSE)))
|
|
goto Exit;
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
// IDs with security descriptors
|
|
|
|
GetSchemaCache()->GetPropertyID(L"__SECURITY_DESCRIPTOR", 1,
|
|
0, REPDRVR_IGNORE_CIMTYPE, dwSecurity);
|
|
|
|
hr = GetFirst_ClassImagesByPropertyId(pConn, dwSecurity, ci);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
((CWmiDbController *)m_pController)->AddSecurityDescriptor(ci.dObjectId);
|
|
|
|
hr = GetNext_ClassImages(pConn, ci);
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
}
|
|
|
|
Exit:
|
|
|
|
if (m_pController)
|
|
GetSQLCache()->ReleaseConnection(pConn, hr, IsDistributed());
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetSuperClassInfo
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetSuperClassInfo(CSQLConnection *pConn, CSchemaCache *pCache, SQL_ID dClassId, BOOL &bKeyless,
|
|
SQLIDs *pLockedIDs)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
CLASSMAP cd;
|
|
OBJECTMAP oj;
|
|
SQL_ID dSuperClass = 0;
|
|
|
|
hr = GetFirst_ClassMap(pConn, dClassId, cd);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
dSuperClass = cd.dSuperClassId;
|
|
|
|
pCache->LockDynasty(dSuperClass);
|
|
pLockedIDs->push_back(dSuperClass);
|
|
|
|
hr = GetFirst_ObjectMap(pConn, dClassId, oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//DEBUGTRACE((LOG_WBEMCORE, "GetSuperClassInfo %S\n", cd.sClassName));
|
|
|
|
if (oj.iObjectFlags & REPDRVR_FLAG_ABSTRACT ||
|
|
oj.iObjectFlags & REPDRVR_FLAG_UNKEYED)
|
|
bKeyless = TRUE;
|
|
|
|
hr = pCache->AddClassInfo(cd.dClassId,
|
|
cd.sClassName, cd.dSuperClassId, cd.dDynastyId, oj.dObjectScopeId, oj.sObjectKey, oj.iObjectFlags);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = LoadSchemaProperties (pConn, pCache, dClassId);
|
|
if (SUCCEEDED(hr) && dSuperClass && dSuperClass != 1)
|
|
hr = GetSuperClassInfo(pConn, pCache, dSuperClass, bKeyless, pLockedIDs);
|
|
}
|
|
}
|
|
|
|
cd.Clear();
|
|
oj.Clear();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// GetDerivedClassInfo
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT GetDerivedClassInfo(CSQLConnection *pConn, CSchemaCache *pCache, SQL_ID dClassId)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
SQLIDs ids;
|
|
|
|
CLASSMAP cd;
|
|
OBJECTMAP oj;
|
|
SQL_ID dClass = 0;
|
|
|
|
if (dClassId != 1)
|
|
{
|
|
hr = GetFirst_ClassMapBySuperClass(pConn, dClassId, cd);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
ids.push_back(cd.dClassId);
|
|
|
|
hr = GetNext_ClassMap(pConn, cd);
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
for (int i = 0; i < ids.size(); i++)
|
|
{
|
|
dClass = ids.at(i);
|
|
|
|
if (!pCache->Exists(dClass))
|
|
{
|
|
hr = GetFirst_ClassMap(pConn, dClass, cd);
|
|
hr = GetFirst_ObjectMap(pConn, dClass, oj);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//DEBUGTRACE((LOG_WBEMCORE, "GetDerivedClassInfo %S\n", cd.sClassName));
|
|
|
|
hr = pCache->AddClassInfo(cd.dClassId,
|
|
cd.sClassName, cd.dSuperClassId, cd.dDynastyId, oj.dObjectScopeId, oj.sObjectKey, oj.iObjectFlags);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = LoadSchemaProperties (pConn, pCache, dClass);
|
|
if (SUCCEEDED(hr))
|
|
hr = GetDerivedClassInfo(pConn, pCache, dClass);
|
|
}
|
|
}
|
|
|
|
cd.Clear();
|
|
oj.Clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::LoadClassInfo
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CWmiDbSession::LoadClassInfo (CSQLConnection *_pConn, SQL_ID dClassId, BOOL bDeep)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
BOOL bRelease = FALSE;
|
|
CSQLConnection *pConn = _pConn;
|
|
_WMILockit lkt(GetCS());
|
|
|
|
DWORD dwSize = GetSchemaCache()->GetTotalSize();
|
|
DWORD dwMax = GetSchemaCache()->GetMaxSize();
|
|
int i = 0;
|
|
|
|
if (dwMax <= dwSize)
|
|
{
|
|
DEBUGTRACE((LOG_WBEMCORE, "Repository schema cache has exceeded limit of %ld bytes (%ld). Resizing...\n", dwMax, dwSize));
|
|
|
|
// We do this here, so we ensure that *only* entire dynasties
|
|
// get loaded. Its OK if we exceed the cache as long as
|
|
// everything in the cache is in use.
|
|
|
|
hr = GetSchemaCache()->ResizeCache();
|
|
}
|
|
|
|
|
|
GetSchemaCache()->LockDynasty(dClassId);
|
|
m_Dynasties[GetCurrentThreadId()].push_back(dClassId);
|
|
|
|
// Check if this exists in the cache.
|
|
// If so, stop now.
|
|
|
|
//if (GetSchemaCache()->Exists(dClassId))
|
|
// return WBEM_S_NO_ERROR;
|
|
|
|
if (!pConn && m_pController)
|
|
{
|
|
hr = GetSQLCache()->GetConnection(&pConn, FALSE, IsDistributed());
|
|
if (SUCCEEDED(hr))
|
|
bRelease = TRUE;
|
|
else
|
|
return hr;
|
|
}
|
|
|
|
// Now get all derived classes, and all parent classes.
|
|
// ====================================================
|
|
|
|
BOOL bKeyless = FALSE;
|
|
hr = GetSuperClassInfo(pConn, GetSchemaCache(), dClassId, bKeyless, &m_Dynasties[GetCurrentThreadId()]);
|
|
if (SUCCEEDED(hr) && (!bKeyless || bDeep))
|
|
hr = GetDerivedClassInfo(pConn, GetSchemaCache(), dClassId);
|
|
|
|
if (bRelease && m_pController)
|
|
GetSQLCache()->ReleaseConnection(pConn);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::LoadClassInfo
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CWmiDbSession::LoadClassInfo (CSQLConnection *_pConn, LPCWSTR lpDynasty, SQL_ID dScopeId, BOOL bDeep)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
DWORD dwSize = GetSchemaCache()->GetTotalSize();
|
|
DWORD dwMax = GetSchemaCache()->GetMaxSize();
|
|
SQLIDs ids;
|
|
int i = 0;
|
|
|
|
if (dwMax <= dwSize)
|
|
{
|
|
DEBUGTRACE((LOG_WBEMCORE, "Repository schema cache has exceeded limit of %ld bytes (%ld). Resizing...\n", dwMax, dwSize));
|
|
|
|
// We do this here, so we ensure that *only* entire dynasties
|
|
// get loaded. Its OK if we exceed the cache as long as
|
|
// everything in the cache is in use.
|
|
|
|
hr = GetSchemaCache()->ResizeCache();
|
|
|
|
}
|
|
|
|
BOOL bRelease = FALSE;
|
|
CSQLConnection *pConn = _pConn;
|
|
|
|
if (!pConn && m_pController)
|
|
{
|
|
hr = GetSQLCache()->GetConnection(&pConn, FALSE, IsDistributed());
|
|
if (SUCCEEDED(hr))
|
|
bRelease = TRUE;
|
|
else
|
|
return hr;
|
|
}
|
|
|
|
CLASSMAP cd;
|
|
OBJECTMAP oj;
|
|
|
|
if (!lpDynasty)
|
|
{
|
|
if ((GetSchemaCache()->Exists(1)))
|
|
return WBEM_S_NO_ERROR;
|
|
|
|
hr = OpenEnum_ClassMap(pConn, cd);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (cd.dSuperClassId == 0)
|
|
ids.push_back(cd.dClassId);
|
|
hr = GetNext_ClassMap(pConn, cd);
|
|
}
|
|
|
|
for (i = 0; i < ids.size(); i++)
|
|
{
|
|
hr = GetFirst_ClassMap(pConn, ids.at(i), cd);
|
|
hr = GetFirst_ObjectMap(pConn, ids.at(i), oj);
|
|
if (SUCCEEDED(hr))
|
|
hr = GetSchemaCache()->AddClassInfo(oj.dObjectId,
|
|
cd.sClassName, cd.dSuperClassId, cd.dDynastyId, oj.dObjectScopeId, oj.sObjectKey, oj.iObjectFlags);
|
|
cd.Clear();
|
|
oj.Clear();
|
|
|
|
if (FAILED(hr))
|
|
break;
|
|
|
|
hr = LoadSchemaProperties (pConn, &((CWmiDbController *)m_pController)->SchemaCache, ids.at(i));
|
|
if (FAILED(hr))
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// We need to find all classes derived from
|
|
// this dynasty.
|
|
|
|
SQL_ID dDynasty = 0;
|
|
BOOL bFound = FALSE;
|
|
|
|
hr = GetFirst_ClassMapByName(pConn, lpDynasty, cd);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
hr = GetFirst_ObjectMap(pConn, cd.dClassId, oj);
|
|
if (!oj.dObjectScopeId || oj.dObjectScopeId == dScopeId)
|
|
{
|
|
oj.Clear();
|
|
cd.Clear();
|
|
bFound = TRUE;
|
|
dDynasty = cd.dClassId;
|
|
break;
|
|
}
|
|
oj.Clear();
|
|
hr = GetNext_ClassMap(pConn, cd);
|
|
}
|
|
|
|
if (bFound)
|
|
hr = LoadClassInfo(pConn, dDynasty, bDeep);
|
|
else
|
|
hr = WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
if (bRelease && m_pController)
|
|
GetSQLCache()->ReleaseConnection(pConn);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::ExecQuery
|
|
//
|
|
//***************************************************************************
|
|
HRESULT STDMETHODCALLTYPE CWmiDbSession::ExecQuery(
|
|
/* [in] */ IWmiDbHandle __RPC_FAR *pScope,
|
|
/* [in] */ IWbemQuery __RPC_FAR *pQuery,
|
|
/* [in] */ DWORD dwFlags,
|
|
/* [in] */ DWORD dwHandleType,
|
|
/* [out] */ DWORD *dwMessageFlags,
|
|
/* [out] */ IWmiDbIterator __RPC_FAR *__RPC_FAR *pQueryResult)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
if (!m_pController ||
|
|
((CWmiDbController *)m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN)
|
|
return WBEM_E_SHUTTING_DOWN;
|
|
|
|
if (dwHandleType == WMIDB_HANDLE_TYPE_INVALID || !pQuery || !pQueryResult || !pScope)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
if (dwHandleType & ~WMIDB_HANDLE_TYPE_COOKIE
|
|
&~WMIDB_HANDLE_TYPE_VERSIONED &~WMIDB_HANDLE_TYPE_PROTECTED
|
|
&~WMIDB_HANDLE_TYPE_EXCLUSIVE &~ WMIDB_HANDLE_TYPE_WEAK_CACHE
|
|
&~WMIDB_HANDLE_TYPE_STRONG_CACHE &~ WMIDB_HANDLE_TYPE_NO_CACHE
|
|
&~WMIDB_HANDLE_TYPE_SUBSCOPED)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
if (dwFlags & ~WMIDB_FLAG_QUERY_DEEP &~WMIDB_FLAG_QUERY_SHALLOW & ~WBEM_FLAG_USE_SECURITY_DESCRIPTOR)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
try
|
|
{
|
|
if (dwMessageFlags)
|
|
*dwMessageFlags = WBEM_REQUIREMENTS_STOP_POSTFILTER;
|
|
|
|
DWORD dwOpenTable = 0;
|
|
SQL_ID dClassId = 0;
|
|
JET_TABLEID tableid = 0;
|
|
|
|
CSQLConnection *pConn = NULL;
|
|
|
|
// Obtain a database connection
|
|
|
|
if (m_pController)
|
|
hr = GetSQLCache()->GetConnection(&pConn, FALSE, IsDistributed());
|
|
|
|
if (FAILED(hr) || !pQuery || !pScope)
|
|
{
|
|
hr = WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
BOOL bDeleteQuery = FALSE;
|
|
|
|
SQL_ID dwNsId = 0;
|
|
IWbemClassObject *pTemp = NULL;
|
|
CESETokens *pToks = NULL;
|
|
int iLastPos = 0;
|
|
BOOL bEnum = FALSE;
|
|
BOOL bWQL = TRUE;
|
|
BOOL bClasses = FALSE;
|
|
int iStartCrit = 0;
|
|
HRESULT hrMatch = WBEM_S_NO_ERROR;
|
|
|
|
dwNsId = ((CWmiDbHandle *)pScope)->m_dObjectId;
|
|
SQL_ID dScopeClassId = ((CWmiDbHandle *)pScope)->m_dClassId;
|
|
SQL_ID dSuperScope = ((CWmiDbHandle *)pScope)->m_dScopeId;
|
|
DWORD dwScopeType = ((CWmiDbHandle *)pScope)->m_dwHandleType ;
|
|
|
|
if (pScope && !(dwScopeType & WMIDB_HANDLE_TYPE_CONTAINER))
|
|
hr=VerifyObjectSecurity (pConn, dwNsId, dScopeClassId, dSuperScope, 0, WBEM_ENABLE);
|
|
|
|
|
|
SWbemAssocQueryInf *pNode = NULL;
|
|
hr = pQuery->GetAnalysis(WMIQ_ANALYSIS_ASSOC_QUERY,
|
|
0, (void **)&pNode);
|
|
if (FAILED(hr))
|
|
{
|
|
BOOL bIndexCols = FALSE, bHierarchy = 0, bSuperSet = FALSE;
|
|
|
|
// Since ESE has no query engine, we need to:
|
|
// Parse the query
|
|
// Figure out which index to use and prefilter
|
|
// slap the parsed output onto the iterator as a post-filter.
|
|
// if the query includes elements that cannot be handled in memory,
|
|
// we need to return WBEM_E_INVALID_QUERY or WBEM_E_PROVIDER_NOT_CAPABLE
|
|
// ================================================================
|
|
|
|
CESEBuilder bldr(&((CWmiDbController *)m_pController)->SchemaCache, this, pConn);
|
|
|
|
hr = bldr.FormatSQL(((CWmiDbHandle *)pScope)->m_dObjectId, ((CWmiDbHandle *)pScope)->m_dClassId,
|
|
((CWmiDbHandle *)pScope)->m_dScopeId, pQuery, &pToks, dwFlags,
|
|
((CWmiDbHandle *)pScope)->m_dwHandleType, &dClassId, &bHierarchy,
|
|
&bIndexCols, &bSuperSet, &bDeleteQuery);
|
|
|
|
// Make sure we have access to the target class.
|
|
// We won't check locks at this point, since that will
|
|
// be the iterator's job.
|
|
|
|
// If we can't analyze this query,
|
|
// we certainly can't delete the results.
|
|
if (bDeleteQuery && bSuperSet)
|
|
hr = WBEM_E_NOT_SUPPORTED;
|
|
|
|
if (!pToks && SUCCEEDED(hr))
|
|
hr = WBEM_E_INVALID_QUERY;
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (dwMessageFlags)
|
|
*dwMessageFlags = (bSuperSet ? WBEM_REQUIREMENTS_START_POSTFILTER : WBEM_REQUIREMENTS_STOP_POSTFILTER);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
int i;
|
|
BOOL bEnumSubClass = TRUE;
|
|
SQL_ID dClassCrit = 0, dSuperClassCrit = 0, dDynastyCrit = 0;
|
|
|
|
if (dClassId == 1) // meta_class - we only want classes
|
|
{
|
|
bClasses = TRUE;
|
|
bEnumSubClass = FALSE;
|
|
|
|
// * __Class = ... => Limit to single class
|
|
// * __SuperClass = => Prescan on SuperClassId
|
|
// * __Dynasty = => Prescan on DynastyId
|
|
// * __this isa => Enum subclasses + list criteria.
|
|
|
|
DWORD dwClassPropID = 0, dwSuperClassPropID = 0, dwDynastyPropID = 0;
|
|
DWORD dwDerivationPropID = 0;
|
|
BOOL bClassCrit = FALSE, bSuperClassCrit = FALSE, bDynastyCrit = FALSE;
|
|
|
|
GetSchemaCache()->GetPropertyID(L"__Class", 1,
|
|
0, REPDRVR_IGNORE_CIMTYPE, dwClassPropID);
|
|
GetSchemaCache()->GetPropertyID(L"__SuperClass", 1,
|
|
0, REPDRVR_IGNORE_CIMTYPE, dwSuperClassPropID);
|
|
GetSchemaCache()->GetPropertyID(L"__Dynasty", 1,
|
|
0, REPDRVR_IGNORE_CIMTYPE, dwDynastyPropID);
|
|
GetSchemaCache()->GetPropertyID(L"__Derivation", 1,
|
|
0, REPDRVR_IGNORE_CIMTYPE, dwDerivationPropID);
|
|
|
|
BOOL bFound = FALSE;
|
|
for (i = 0; i < pToks->GetNumTokens(); i++)
|
|
{
|
|
ESEToken *pTok = pToks->GetToken(i);
|
|
if (pTok && pTok->tokentype == ESE_EXPR_TYPE_EXPR)
|
|
{
|
|
if (((ESEWQLToken *)pTok)->tokentype == ESE_EXPR_TYPE_OR ||
|
|
((ESEWQLToken *)pTok)->tokentype == ESE_EXPR_TYPE_NOT)
|
|
{
|
|
bClassCrit = 0;
|
|
bSuperClassCrit = 0;
|
|
bDynastyCrit = 0;
|
|
break;
|
|
}
|
|
if (((ESEWQLToken *)pTok)->optype == WQL_TOK_EQ)
|
|
{
|
|
SQL_ID dClassId2 = 0, dDynasty = 0;
|
|
|
|
if (wcslen((((ESEWQLToken *)pTok)->Value.sValue)))
|
|
{
|
|
hr = GetSchemaCache()->GetClassID
|
|
(((ESEWQLToken *)pTok)->Value.sValue, dwNsId, dClassId2, &dDynasty);
|
|
}
|
|
|
|
if ((((ESEWQLToken *)pTok)->dPropertyId == dwClassPropID))
|
|
{
|
|
bClassCrit = TRUE;
|
|
dClassCrit = dClassId2;
|
|
}
|
|
else if ((((ESEWQLToken *)pTok)->dPropertyId == dwSuperClassPropID))
|
|
{
|
|
bSuperClassCrit = TRUE;
|
|
dSuperClassCrit = dClassId2;
|
|
}
|
|
else if ((((ESEWQLToken *)pTok)->dPropertyId == dwDynastyPropID))
|
|
{
|
|
bDynastyCrit = TRUE;
|
|
dDynastyCrit = dClassId2;
|
|
}
|
|
else if ((((ESEWQLToken *)pTok)->dPropertyId == dwDerivationPropID))
|
|
{
|
|
bDynastyCrit = TRUE;
|
|
dDynastyCrit = dDynasty;
|
|
dClassId = dClassId2;
|
|
if (dDynasty != dClassId2)
|
|
{
|
|
bEnumSubClass = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
pToks->SetIsMetaClass(TRUE);
|
|
|
|
if (bClassCrit)
|
|
{
|
|
OBJECTMAP oj;
|
|
hrMatch = GetFirst_ObjectMap(pConn, dClassCrit, oj);
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ObjectMap");
|
|
dwOpenTable = OPENTABLE_OBJECTMAP;
|
|
oj.Clear();
|
|
}
|
|
else if (bSuperClassCrit)
|
|
{
|
|
CLASSMAP cm;
|
|
if (!dSuperClassCrit)
|
|
dSuperClassCrit = 1;
|
|
hrMatch = GetFirst_ClassMapBySuperClass(pConn, dSuperClassCrit, cm);
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ClassMap");
|
|
dwOpenTable = OPENTABLE_CLASSMAP;
|
|
cm.Clear();
|
|
}
|
|
else if (bDynastyCrit)
|
|
{
|
|
CLASSMAP cm;
|
|
hrMatch = GetFirst_ClassMapByDynasty(pConn, dDynastyCrit, cm);
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ClassMap");
|
|
dwOpenTable = OPENTABLE_CLASSMAP;
|
|
cm.Clear();
|
|
}
|
|
else // Scan all ClassMap
|
|
{
|
|
pToks->AddSysExpr(0, dClassId);
|
|
CLASSMAP cm;
|
|
hrMatch = OpenEnum_ClassMap(pConn, cm);
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ClassMap");
|
|
dwOpenTable = OPENTABLE_CLASSMAP;
|
|
cm.Clear();
|
|
}
|
|
|
|
}
|
|
|
|
if (bEnumSubClass)
|
|
{
|
|
// If we need to limit the classes by class ID
|
|
// get the derived class list.
|
|
// Disregard if this is meta_class - we're only
|
|
// interested in returning classes.
|
|
|
|
SQL_ID *pIDs = NULL;
|
|
int iNumChildren = 0;
|
|
|
|
GetSchemaCache()->GetDerivedClassList(dClassId, &pIDs, iNumChildren, FALSE);
|
|
if (pIDs)
|
|
{
|
|
for (i = iNumChildren-1; i >= 0; i--)
|
|
{
|
|
SQL_ID d = pIDs[i];
|
|
pToks->AddSysExpr(0, d);
|
|
}
|
|
delete pIDs;
|
|
}
|
|
// Optimization for class with no children.
|
|
if (!iNumChildren && pToks->IsMetaClass() && (dClassId != 1))
|
|
{
|
|
CLASSMAP cm;
|
|
hrMatch = GetFirst_ClassMap(pConn, dClassId, cm);
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ClassMap");
|
|
dwOpenTable = OPENTABLE_CLASSMAP;
|
|
cm.Clear();
|
|
}
|
|
}
|
|
|
|
if ( ((CWmiDbHandle *)pScope)->m_dwHandleType & WMIDB_HANDLE_TYPE_CONTAINER)
|
|
{
|
|
CONTAINEROBJ co;
|
|
hrMatch = GetFirst_ContainerObjs(pConn, ((CWmiDbHandle *)pScope)->m_dObjectId, co);
|
|
co.Clear();
|
|
dwOpenTable = OPENTABLE_CONTAINEROBJS;
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ContainerObjs");
|
|
}
|
|
else
|
|
{
|
|
if (bIndexCols)
|
|
{
|
|
// Seek to property ID of first indexed criteria
|
|
|
|
DWORD dwNumToks = pToks->GetNumTokens();
|
|
for (i = 0; i < dwNumToks; i++)
|
|
{
|
|
ESEToken *pTok = pToks->GetToken(i);
|
|
if (pTok && pTok->tokentype == ESE_EXPR_TYPE_EXPR)
|
|
{
|
|
INDEXDATA id;
|
|
iLastPos = i;
|
|
DWORD dwPos = 0;
|
|
|
|
ESEWQLToken *pTok2 = (ESEWQLToken *)pTok;
|
|
if (pTok2->bIndexed)
|
|
{
|
|
switch(pTok2->Value.valuetype)
|
|
{
|
|
case ESE_VALUE_TYPE_SQL_ID:
|
|
SetupIndexDataAccessor(pConn, WMIDB_STORAGE_NUMERIC, dwPos, NULL);
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"IndexNumericData");
|
|
hrMatch = GetFirst_IndexDataByProperty(pConn, pTok2->dPropertyId,
|
|
id, tableid, SQL_POS_INDEXNUMERIC);
|
|
dwOpenTable = OPENTABLE_INDEXNUMERIC;
|
|
id.Clear();
|
|
break;
|
|
case ESE_VALUE_TYPE_STRING:
|
|
SetupIndexDataAccessor(pConn, WMIDB_STORAGE_STRING, dwPos, NULL);
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"IndexStringData");
|
|
hrMatch = GetFirst_IndexDataByProperty(pConn, pTok2->dPropertyId,
|
|
id, tableid, SQL_POS_INDEXSTRING);
|
|
dwOpenTable = OPENTABLE_INDEXSTRING;
|
|
id.Clear();
|
|
break;
|
|
case ESE_VALUE_TYPE_REAL:
|
|
SetupIndexDataAccessor(pConn, WMIDB_STORAGE_REAL, dwPos, NULL);
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"IndexRealData");
|
|
hrMatch = GetFirst_IndexDataByProperty(pConn, pTok2->dPropertyId,
|
|
id, tableid, SQL_POS_INDEXREAL);
|
|
dwOpenTable = OPENTABLE_INDEXREAL;
|
|
id.Clear();
|
|
break;
|
|
case ESE_VALUE_TYPE_REF:
|
|
SetupIndexDataAccessor(pConn, WMIDB_STORAGE_REFERENCE, dwPos, NULL);
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"IndexRefData");
|
|
hrMatch = GetFirst_IndexDataByProperty(pConn, pTok2->dPropertyId,
|
|
id, tableid, SQL_POS_INDEXREF);
|
|
dwOpenTable = OPENTABLE_INDEXREF;
|
|
id.Clear();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (dwOpenTable)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!dwOpenTable)
|
|
{
|
|
dwOpenTable = OPENTABLE_OBJECTMAP;
|
|
|
|
OBJECTMAP oj;
|
|
// Find the first class that matches.
|
|
DWORD dwNumToks = pToks->GetNumTokens();
|
|
for (i = 0; i < dwNumToks; i++)
|
|
{
|
|
ESEToken *pTok = pToks->GetToken(i);
|
|
if (pTok->tokentype == ESE_EXPR_TYPE_EXPR)
|
|
{
|
|
ESEWQLToken *pTok2 = (ESEWQLToken *)pTok;
|
|
if (pTok2->Value.valuetype == ESE_VALUE_TYPE_SYSPROP)
|
|
{
|
|
if (pTok2->dClassId)
|
|
{
|
|
hrMatch = GetFirst_ObjectMapByClass(pConn, pTok2->dClassId, oj);
|
|
if (SUCCEEDED(hrMatch))
|
|
{
|
|
oj.Clear();
|
|
iLastPos = i;
|
|
break;
|
|
}
|
|
oj.Clear();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ObjectMap");
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SQL_ID dObjId = 0;
|
|
CESEBuilder bldr(&((CWmiDbController *)m_pController)->SchemaCache, this, pConn);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Get dObjId.
|
|
SQL_ID dAssocClassId = 0, dResultClassId = 0;
|
|
|
|
IWbemPath *pPath = NULL;
|
|
hr = CoCreateInstance(CLSID_WbemDefPath, 0, CLSCTX_INPROC_SERVER,
|
|
IID_IWbemPath, (LPVOID *) &pPath);
|
|
|
|
BOOL bIsClass = FALSE;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CReleaseMe r (pPath);
|
|
pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, pNode->m_pszPath);
|
|
IWmiDbHandle *pTemp = NULL;
|
|
hr = GetObject(pScope, pPath, dwFlags, WMIDB_HANDLE_TYPE_COOKIE, &pTemp);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// We need rudimentary tempQL support
|
|
BOOL bSuperSet = FALSE;
|
|
|
|
dObjId = ((CWmiDbHandle *)pTemp)->m_dObjectId;
|
|
bIsClass = ((CWmiDbHandle *)pTemp)->m_dClassId == 1 ? TRUE: FALSE;
|
|
|
|
pTemp->Release();
|
|
hr = bldr.FormatSQL(((CWmiDbHandle *)pScope)->m_dObjectId, ((CWmiDbHandle *)pScope)->m_dClassId,
|
|
((CWmiDbHandle *)pScope)->m_dScopeId, dObjId, pNode->m_pszResultClass,
|
|
pNode->m_pszAssocClass, pNode->m_pszRole, pNode->m_pszResultRole, pNode->m_pszRequiredQualifier,
|
|
pNode->m_pszRequiredAssocQualifier, pNode->m_uFeatureMask, &pToks, dwFlags,
|
|
((CWmiDbHandle *)pScope)->m_dwHandleType, &dAssocClassId, &dResultClassId, &bSuperSet);
|
|
|
|
bWQL = FALSE;
|
|
|
|
if (!pToks && SUCCEEDED(hr))
|
|
hr = WBEM_E_INVALID_QUERY;
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (dwMessageFlags)
|
|
{
|
|
*dwMessageFlags = (bSuperSet ? WBEM_REQUIREMENTS_START_POSTFILTER : WBEM_REQUIREMENTS_STOP_POSTFILTER);
|
|
|
|
if (pNode->m_uFeatureMask & (QUERY_TYPE_SCHEMA_ONLY + QUERY_TYPE_CLASSDEFS_ONLY))
|
|
*dwMessageFlags = TRUE;
|
|
}
|
|
|
|
hr=VerifyClassSecurity (pConn, dObjId, WBEM_ENABLE);
|
|
if (SUCCEEDED(hr) && dAssocClassId)
|
|
{
|
|
hr=VerifyClassSecurity (pConn, dAssocClassId, WBEM_ENABLE);
|
|
}
|
|
if (SUCCEEDED(hr) && dResultClassId)
|
|
{
|
|
hr=VerifyClassSecurity(pConn, dResultClassId, WBEM_ENABLE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pQuery->FreeMemory(pNode);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (!bIsClass)
|
|
{
|
|
// Use the target object, REFID
|
|
|
|
INDEXDATA is;
|
|
DWORD dwPos = 0;
|
|
hrMatch = GetFirst_IndexDataRef(pConn, dObjId, is, tableid, dwPos);
|
|
dwOpenTable = OPENTABLE_INDEXREF;
|
|
is.Clear();
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"IndexRefData");
|
|
}
|
|
else
|
|
{
|
|
// We need to examine each class, and see if it contains
|
|
// an association or reference to the target class.
|
|
|
|
REFERENCEPROPERTIES pm;
|
|
hrMatch = GetFirst_ReferencePropertiesByRef (pConn, dObjId, pm);
|
|
dwOpenTable = OPENTABLE_REFPROPS;
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ReferenceProperties");
|
|
if (dwMessageFlags)
|
|
*dwMessageFlags = WBEM_REQUIREMENTS_START_POSTFILTER;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Construct and return the iterator.
|
|
// This contains the open SQL connection positioned
|
|
// on the first valid row
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD dwRows;
|
|
CWmiESEIterator *pNew = new CWmiESEIterator;
|
|
if (pNew)
|
|
{
|
|
AddRef_Lock();
|
|
pNew->m_pSession = this;
|
|
pNew->m_pConn = pConn;
|
|
pNew->m_pToks = pToks;
|
|
if (SUCCEEDED(hrMatch))
|
|
pNew->m_dwOpenTable = dwOpenTable;
|
|
else
|
|
pNew->m_dwOpenTable = 0;
|
|
|
|
pNew->m_tableid = tableid;
|
|
pNew->m_iLastPos = iLastPos;
|
|
if (bEnum)
|
|
pNew->m_iStartPos = iStartCrit;
|
|
else
|
|
pNew->m_iStartPos = 0;
|
|
pNew->m_bEnum = bEnum;
|
|
pNew->m_bWQL = bWQL;
|
|
pNew->m_bClasses = bClasses;
|
|
pNew->AddRef();
|
|
AddRef(); // The iterator releases us on its own release
|
|
|
|
// If this was a delete query,
|
|
// enumerate the results, and delete 'em
|
|
|
|
if (bDeleteQuery)
|
|
{
|
|
hr = DeleteRows(pScope, pNew, IID_IWmiDbHandle);
|
|
pNew->Release();
|
|
*pQueryResult = NULL;
|
|
}
|
|
|
|
// select query. Give them the iterator
|
|
|
|
else if (pQueryResult)
|
|
{
|
|
*pQueryResult = (IWmiDbIterator *)pNew;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
else
|
|
delete pToks;
|
|
}
|
|
|
|
// If we failed, we need to release the connection
|
|
// Otherwise, it will be attached to the iterator,
|
|
// and will be released when the last result row has been returned
|
|
|
|
if (FAILED(hr) && pConn && m_pController)
|
|
GetSQLCache()->ReleaseConnection(pConn);
|
|
}
|
|
catch (...)
|
|
{
|
|
ERRORTRACE((LOG_WBEMCORE, "Fatal error in CWmiDbSession::ExecQuery\n"));
|
|
hr = WBEM_E_CRITICAL_ERROR;
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::Enumerate
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT STDMETHODCALLTYPE CWmiDbSession::Enumerate(
|
|
/* [in] */ IWmiDbHandle __RPC_FAR *pScope,
|
|
/* [in] */ DWORD dwFlags,
|
|
/* [in] */ DWORD dwRequestedHandleType,
|
|
/* [out] */ IWmiDbIterator __RPC_FAR *__RPC_FAR *ppQueryResult)
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
|
|
if (!m_pController ||
|
|
((CWmiDbController *)m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN)
|
|
return WBEM_E_SHUTTING_DOWN;
|
|
|
|
if (dwRequestedHandleType == WMIDB_HANDLE_TYPE_INVALID || !pScope)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
if (dwRequestedHandleType & ~WMIDB_HANDLE_TYPE_COOKIE
|
|
&~WMIDB_HANDLE_TYPE_VERSIONED &~WMIDB_HANDLE_TYPE_PROTECTED
|
|
&~WMIDB_HANDLE_TYPE_EXCLUSIVE &~ WMIDB_HANDLE_TYPE_WEAK_CACHE
|
|
&~WMIDB_HANDLE_TYPE_STRONG_CACHE &~ WMIDB_HANDLE_TYPE_NO_CACHE
|
|
&~WMIDB_HANDLE_TYPE_SUBSCOPED &~WMIDB_HANDLE_TYPE_CONTAINER
|
|
&~ WMIDB_HANDLE_TYPE_SCOPE)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
try
|
|
{
|
|
{
|
|
_WMILockit lkt(GetCS());
|
|
|
|
if (!((CWmiDbController *)m_pController)->m_bCacheInit)
|
|
{
|
|
hr = LoadSchemaCache();
|
|
if (SUCCEEDED(hr))
|
|
((CWmiDbController *)m_pController)->m_bCacheInit = TRUE;
|
|
else
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
JET_TABLEID tableid = 0;
|
|
MappedProperties *pProps;
|
|
DWORD dwNumProps;
|
|
BOOL bHierarchy = FALSE;
|
|
|
|
SQL_ID dwNsId = 0, dClassId = 0;
|
|
_bstr_t sPath;
|
|
int iNumRows = 0;
|
|
IWbemClassObject *pTemp = NULL;
|
|
|
|
if (pScope)
|
|
{
|
|
// CVADAI: This is a container, not a scope, so this
|
|
// info won't be cached.
|
|
|
|
dwNsId = ((CWmiDbHandle *)pScope)->m_dObjectId;
|
|
dClassId = ((CWmiDbHandle *)pScope)->m_dClassId;
|
|
//SQL_ID dScopeId = ((CWmiDbHandle *)pScope)->m_dScopeId;
|
|
|
|
//hr = VerifyObjectSecurity(dwNsId, dClassId, dScopeId, 0, WBEM_ENABLE);
|
|
}
|
|
if (SUCCEEDED(hr) && m_pController)
|
|
{
|
|
DWORD dwRows;
|
|
IRowset *pRowset = NULL;
|
|
CSQLConnection *pConn=NULL;
|
|
|
|
hr = GetSQLCache()->GetConnection(&pConn, FALSE, IsDistributed());
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Here we need to do the equivalent enumeration based
|
|
// on table or index scan, and return a custom iterator
|
|
// Basically, we stuff the filter conditions on the iterator,
|
|
// and return it.
|
|
// ====================================================
|
|
|
|
DWORD dwOpenTable = 0;
|
|
CESETokens *pToks = NULL;
|
|
wchar_t sSQL [1024];
|
|
DWORD dwHandleType = ((CWmiDbHandle *)pScope)->m_dwHandleType;
|
|
|
|
if (dClassId == INSTANCESCLASSID)
|
|
{
|
|
// ClassId = dwNsId AND
|
|
// ObjectScopeId = dScopeId
|
|
|
|
OBJECTMAP oj;
|
|
SQL_ID dScopeId = ((CWmiDbHandle *)pScope)->m_dScopeId;
|
|
|
|
hr = GetFirst_ObjectMapByClass(pConn, dwNsId, oj);
|
|
oj.Clear();
|
|
if (SUCCEEDED(hr))
|
|
dwOpenTable = OPENTABLE_OBJECTMAP;
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ObjectMap");
|
|
|
|
pToks = new CESETokens;
|
|
if (pToks)
|
|
pToks->AddSysExpr(dScopeId, dwNsId);
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
}
|
|
else if (dwHandleType & WMIDB_HANDLE_TYPE_CONTAINER)
|
|
{
|
|
// ContainerId = dContainerId (Use ContainerObjs)
|
|
|
|
SQL_ID dContainerId = ((CWmiDbHandle *)pScope)->m_dObjectId;
|
|
pToks = new CESETokens;
|
|
if (pToks)
|
|
{
|
|
CONTAINEROBJ co;
|
|
hr = GetFirst_ContainerObjs(pConn, dContainerId, co);
|
|
if (SUCCEEDED(hr))
|
|
dwOpenTable = OPENTABLE_CONTAINEROBJS;
|
|
co.Clear();
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ContainerObjs");
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
// Scope
|
|
else
|
|
{
|
|
// ObjectScopeId = dwNsId
|
|
OBJECTMAP oj;
|
|
SQL_ID dScopeId = ((CWmiDbHandle *)pScope)->m_dObjectId;
|
|
|
|
hr = GetFirst_ObjectMapByScope(pConn, dScopeId, oj);
|
|
oj.Clear();
|
|
if (SUCCEEDED(hr))
|
|
dwOpenTable = OPENTABLE_OBJECTMAP;
|
|
tableid = ((CESEConnection *)pConn)->GetTableID(L"ObjectMap");
|
|
pToks = new CESETokens;
|
|
if (pToks)
|
|
pToks->AddSysExpr(dScopeId, 0);
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
if (hr == WBEM_E_NOT_FOUND)
|
|
hr = WBEM_S_NO_ERROR; // create the iterator, for consistency.
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CWmiESEIterator *pNew = new CWmiESEIterator;
|
|
if (pNew)
|
|
{
|
|
*ppQueryResult = (IWmiDbIterator *)pNew;
|
|
|
|
pNew->m_pConn = pConn; // Releasing the iterator will release this guy.
|
|
pNew->m_pSession = this;
|
|
pNew->m_pConn = pConn;
|
|
pNew->m_pToks = pToks;
|
|
pNew->m_dwOpenTable = dwOpenTable;
|
|
pNew->m_tableid = tableid;
|
|
pNew->AddRef();
|
|
AddRef();
|
|
}
|
|
else
|
|
{
|
|
if (m_pController)
|
|
GetSQLCache()->ReleaseConnection(pConn);
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_pController)
|
|
GetSQLCache()->ReleaseConnection(pConn);
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
ERRORTRACE((LOG_WBEMCORE, "Fatal error in CWmiDbSession::Enumerate\n"));
|
|
hr = WBEM_E_CRITICAL_ERROR;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CWmiDbSession::InsertArray
|
|
//
|
|
//***************************************************************************
|
|
|
|
HRESULT CWmiDbSession::InsertArray(CSQLConnection *pConn,IWmiDbHandle *pScope,
|
|
SQL_ID dObjectId, SQL_ID dClassId,
|
|
DWORD dwPropertyID, VARIANT &vValue, long lFlavor, DWORD dwRefID,
|
|
LPCWSTR lpObjectKey , LPCWSTR lpPath , SQL_ID dScope, CIMTYPE ct )
|
|
{
|
|
HRESULT hr = WBEM_S_NO_ERROR;
|
|
IRowset *pIRowset = NULL;
|
|
DWORD dwRows = 0;
|
|
if (!m_pController ||
|
|
((CWmiDbController *)m_pController)->m_dwCurrentStatus == WBEM_E_SHUTTING_DOWN)
|
|
return WBEM_E_SHUTTING_DOWN;
|
|
|
|
if (vValue.vt == VT_UNKNOWN)
|
|
{
|
|
BYTE *pBuff = NULL;
|
|
DWORD dwLen = 0;
|
|
IUnknown *pUnk = V_UNKNOWN (&vValue);
|
|
if (pUnk)
|
|
{
|
|
_IWmiObject *pInt = NULL;
|
|
hr = pUnk->QueryInterface(IID__IWmiObject, (void **)&pInt);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pInt->GetObjectMemory(NULL, 0, &dwLen);
|
|
pBuff = new BYTE [dwLen];
|
|
if (pBuff)
|
|
{
|
|
CDeleteMe <BYTE> d (pBuff);
|
|
DWORD dwLen1;
|
|
hr = pInt->GetObjectMemory(pBuff, dwLen, &dwLen1);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = CSQLExecProcedure::InsertBlobData(pConn, dClassId, dObjectId,
|
|
dwPropertyID, pBuff, dwRefID, dwLen);
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
pInt->Release();
|
|
}
|
|
}
|
|
}
|
|
else if (((vValue.vt & 0xFFF) == VT_UI1) || vValue.vt == VT_BSTR)
|
|
{
|
|
BYTE *pBuff = NULL;
|
|
DWORD dwLen = 0;
|
|
|
|
// Get the byte buffer out of the safearray.
|
|
|
|
if ((vValue.vt & 0xFFF) == VT_UI1)
|
|
GetByteBuffer(&vValue, &pBuff, dwLen);
|
|
else // its a bstr.
|
|
{
|
|
dwLen = wcslen(vValue.bstrVal)*2+2;
|
|
char * pTemp = new char[dwLen+1];
|
|
if (pTemp)
|
|
{
|
|
sprintf(pTemp, "%S", vValue.bstrVal);
|
|
pBuff = (unsigned char *)pTemp;
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
if (pBuff)
|
|
{
|
|
hr = CSQLExecProcedure::InsertBlobData (pConn, dClassId, dObjectId,
|
|
dwPropertyID, pBuff, 0, dwLen);
|
|
delete pBuff;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bool bIsQfr = FALSE;
|
|
DWORD dwFlags = 0;
|
|
SQL_ID dClassID = 0;
|
|
DWORD dwStorage = 0;
|
|
|
|
hr = GetSchemaCache()->GetPropertyInfo (dwPropertyID, NULL, &dClassID, &dwStorage,
|
|
NULL, &dwFlags);
|
|
|
|
bIsQfr = (dwFlags & REPDRVR_FLAG_QUALIFIER) ? TRUE : FALSE;
|
|
|
|
SAFEARRAY* psaArray = NULL;
|
|
psaArray = V_ARRAY(&vValue);
|
|
if (psaArray)
|
|
{
|
|
long i = 0;
|
|
int iType = vValue.vt & 0xFF;
|
|
|
|
VARIANT vTemp;
|
|
VariantInit(&vTemp);
|
|
|
|
long lLBound, lUBound;
|
|
SafeArrayGetLBound(psaArray, 1, &lLBound);
|
|
SafeArrayGetUBound(psaArray, 1, &lUBound);
|
|
|
|
lUBound -= lLBound;
|
|
lUBound += 1;
|
|
|
|
InsertQfrValues *pQfr = NULL;
|
|
int iPos = 0;
|
|
pQfr = new InsertPropValues[lUBound];
|
|
if (!pQfr)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
ct = ct & 0xFF;
|
|
|
|
for (i = 0; i < lUBound; i++)
|
|
{
|
|
if (ct != CIM_OBJECT)
|
|
{
|
|
if (iType != VT_NULL && iType != VT_EMPTY)
|
|
{
|
|
hr = GetVariantFromArray(psaArray, i, iType, vTemp);
|
|
LPWSTR lpVal = GetStr(vTemp);
|
|
CDeleteMe <wchar_t> r1(lpVal);
|
|
|
|
VariantClear(&vTemp);
|
|
if (FAILED(hr))
|
|
break;
|
|
|
|
//if (wcslen(lpVal))
|
|
{
|
|
pQfr[iPos].iPos = i;
|
|
pQfr[iPos].iQfrID = dwRefID;
|
|
pQfr[iPos].iPropID = dwPropertyID;
|
|
pQfr[iPos].pRefKey = NULL;
|
|
pQfr[iPos].bLong = false;
|
|
pQfr[iPos].bIndexed = (dwFlags & (REPDRVR_FLAG_KEY + REPDRVR_FLAG_INDEXED)) ? TRUE : FALSE;
|
|
pQfr[iPos].iStorageType = dwStorage;
|
|
pQfr[iPos].dClassId = dClassID;
|
|
pQfr[iPos].iFlavor = lFlavor;
|
|
|
|
if (ct == CIM_REFERENCE)
|
|
{
|
|
pQfr[iPos].bIndexed = TRUE; // References are always keys
|
|
|
|
LPWSTR lpTemp = NULL;
|
|
IWbemPath *pPath = NULL;
|
|
|
|
hr = CoCreateInstance(CLSID_WbemDefPath, 0, CLSCTX_INPROC_SERVER,
|
|
IID_IWbemPath, (LPVOID *) &pPath);
|
|
CReleaseMe r8 (pPath);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (lpVal)
|
|
{
|
|
LPWSTR lpStrip = StripQuotes2 (lpVal);
|
|
CDeleteMe <wchar_t> d (lpStrip);
|
|
|
|
pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL, lpStrip);
|
|
|
|
hr = NormalizeObjectPathGet(pScope, pPath, &lpTemp, NULL, NULL, NULL, pConn);
|
|
CDeleteMe <wchar_t> r1(lpTemp);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
LPWSTR lpTemp2 = NULL;
|
|
lpTemp2 = GetKeyString(lpStrip);
|
|
CDeleteMe <wchar_t> d (lpTemp2);
|
|
pQfr[iPos].pRefKey = new wchar_t [21];
|
|
if (pQfr[iPos].pRefKey)
|
|
swprintf(pQfr[iPos].pRefKey, L"%I64d", CRC64::GenerateHashValue(lpTemp2));
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
{
|
|
hr = WBEM_S_NO_ERROR;
|
|
// Strip off the root namespace prefix and generate the
|
|
// pseudo-name. We have no way of knowing if they entered this
|
|
// path correctly.
|
|
|
|
LPWSTR lpTemp3 = StripUnresolvedName (lpStrip);
|
|
CDeleteMe <wchar_t> d2 (lpTemp3);
|
|
|
|
LPWSTR lpTemp2 = NULL;
|
|
lpTemp2 = GetKeyString(lpTemp3);
|
|
CDeleteMe <wchar_t> d (lpTemp2);
|
|
pQfr[iPos].pRefKey = new wchar_t [21];
|
|
if (lpTemp2 && pQfr[iPos].pRefKey)
|
|
swprintf(pQfr[iPos].pRefKey, L"%I64d", CRC64::GenerateHashValue(lpTemp2));
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
|
|
pQfr[iPos].pValue = new wchar_t[wcslen(lpStrip)+1];
|
|
if (pQfr[iPos].pValue)
|
|
wcscpy(pQfr[iPos].pValue,lpStrip);
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
pQfr[iPos].pValue = NULL;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (lpVal)
|
|
{
|
|
pQfr[iPos].pValue = new wchar_t[wcslen(lpVal)+1];
|
|
if (pQfr[iPos].pValue)
|
|
wcscpy(pQfr[iPos].pValue,lpVal);
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
else
|
|
pQfr[iPos].pValue = NULL;
|
|
|
|
pQfr[iPos].pRefKey = NULL;
|
|
}
|
|
iPos++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Can't have default embedded object array values.
|
|
|
|
if (lpPath)
|
|
{
|
|
hr = GetVariantFromArray(psaArray, i, iType, vTemp);
|
|
IUnknown *pTemp = V_UNKNOWN(&vTemp);
|
|
if (pTemp)
|
|
{
|
|
BYTE *pBuff = NULL;
|
|
DWORD dwLen;
|
|
_IWmiObject *pInt = NULL;
|
|
hr = pTemp->QueryInterface(IID__IWmiObject, (void **)&pInt);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pInt->GetObjectMemory(NULL, 0, &dwLen);
|
|
pBuff = new BYTE [dwLen];
|
|
if (pBuff)
|
|
{
|
|
CDeleteMe <BYTE> d (pBuff);
|
|
DWORD dwLen1;
|
|
hr = pInt->GetObjectMemory(pBuff, dwLen, &dwLen1);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = CSQLExecProcedure::InsertBlobData(pConn, dClassId, dObjectId,
|
|
dwPropertyID, pBuff, i, dwLen);
|
|
}
|
|
}
|
|
else
|
|
hr = WBEM_E_OUT_OF_MEMORY;
|
|
|
|
pInt->Release();
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
hr = CSQLExecProcedure::InsertBatch (pConn, dObjectId, 0, 0, pQfr, iPos);
|
|
|
|
// Finally clean up the upper array bounds
|
|
// (if this array used to be bigger...)
|
|
// ====================================
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
CLASSDATA cd;
|
|
IDs ids;
|
|
|
|
hr = GetFirst_ClassData(pConn, dObjectId, cd, dwPropertyID);
|
|
while (SUCCEEDED(hr))
|
|
{
|
|
if (dwPropertyID == cd.iPropertyId &&
|
|
dwRefID == cd.iQfrPos &&
|
|
cd.iArrayPos >= i)
|
|
{
|
|
ids.push_back (cd.iArrayPos);
|
|
}
|
|
hr = GetNext_ClassData(pConn, cd);
|
|
if (dObjectId != cd.dObjectId)
|
|
{
|
|
cd.Clear();
|
|
break;
|
|
}
|
|
}
|
|
hr = WBEM_S_NO_ERROR;
|
|
|
|
for (i = 0; i < ids.size(); i++)
|
|
hr = DeleteClassData(pConn, dwPropertyID, dObjectId, ids.at(i));
|
|
}
|
|
delete pQfr;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CWmiDbSession::CustomGetObject(IWmiDbHandle *pScope, IWbemPath *pPath, LPWSTR lpObjectKey,
|
|
DWORD dwFlags, DWORD dwRequestedHandleType, IWmiDbHandle **ppResult)
|
|
{return E_NOTIMPL;}
|
|
HRESULT CWmiDbSession::CustomGetMapping(CSQLConnection *pConn, IWmiDbHandle *pScope, LPWSTR lpClassName, IWbemClassObject **ppMapping)
|
|
{return E_NOTIMPL;}
|
|
HRESULT CWmiDbSession::CustomCreateMapping(CSQLConnection *pConn, LPWSTR lpClassName, IWbemClassObject *pClassObj, IWmiDbHandle *pScope)
|
|
{return E_NOTIMPL;}
|
|
HRESULT CWmiDbSession::CustomPutInstance(CSQLConnection *pConn, IWmiDbHandle *pScope, SQL_ID dClassId,
|
|
DWORD dwFlags, IWbemClassObject **ppObjToPut, LPWSTR lpClassName)
|
|
{return E_NOTIMPL;}
|
|
HRESULT CWmiDbSession::CustomFormatSQL(IWmiDbHandle *pScope, IWbemQuery *pQuery, _bstr_t &sSQL, SQL_ID *dClassId,
|
|
MappedProperties **ppMapping, DWORD *dwNumProps, BOOL *bCount)
|
|
{return E_NOTIMPL;}
|
|
HRESULT CWmiDbSession::CustomDelete(CSQLConnection *pConn, IWmiDbHandle *pScope, IWmiDbHandle *pHandle, LPWSTR lpClassName)
|
|
{return E_NOTIMPL;}
|
|
|
|
|