Modifying Objects (CDOEX)
Topic Last Modified: 2006-06-12
Visual C++
Note
The following example uses a file URL with the Exchange OLE DB (ExOLEDB) provider. The ExOLEDB provider also supports The HTTP: URL Scheme. Using The HTTP: URL Scheme allows both client and server applications to use a single URL scheme.
// Change folder names, modify appointments and contacts
// Modify the code where you see TODO and make sure the objects or properties exist.
#include <activeds.h>
#include <stdio.h>
#include <conio.h>
#import <msado15.dll> no_namespace rename("EOF","adoEOF")
#import <cdoex.dll> no_namespace
struct StartOle {
StartOle() { CoInitialize(NULL); }
~StartOle() { CoUninitialize(); }
} _inst_StartOle;
void dump_com_error(_com_error &e)
{
printf("Oops - hit an error!\n");
printf("\tCode = %08lx\n", e.Error());
printf("\tCode meaning = %s\n", e.ErrorMessage());
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
printf("\tSource = %s\n", (LPCTSTR) bstrSource);
printf("\tDescription = %s\n", (LPCTSTR) bstrDescription);
}
void ModifyObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfSourceFolder, _bstr_t strSearchSql);
HRESULT GetDomainName(BSTR * bstrDomainName);
void main(void)
{
_bstr_t strDomainName;
_bstr_t strLocalPathOfSourceFolder;
_bstr_t strSourceFolderUrl;
_bstr_t strSearchSql;
_bstr_t strUser;
HRESULT hr = S_OK;
BSTR bstrDomainDNSName;
// Get your domain name.
hr = GetDomainName(&bstrDomainDNSName);
strDomainName = (_bstr_t)bstrDomainDNSName;
strUser = "user1"; // TODO
// Sample 1: List appointments in the user's Calendar folder.
strLocalPathOfSourceFolder = "MBX/" + strUser + "/Calendar";
// Create the SQL query for the recordset (appointments).
strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;
strSearchSql = "select ";
strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
strSearchSql = strSearchSql + ", \"DAV:href\"";
strSearchSql = strSearchSql + ", \"DAV:displayname\"";
strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
strSearchSql = strSearchSql + ", \"DAV:iscollection\"";
strSearchSql = strSearchSql + ", \"urn:schemas:httpmail:subject\"";
strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = false";
// TODO
strSearchSql = strSearchSql + " AND \"urn:schemas:httpmail:subject\" = 'Test Appointment'";
ModifyObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);
// Sample 2: Modify the contacts with the nickname "Small" in Contacts.
strLocalPathOfSourceFolder = "MBX/" + strUser + "/Contacts";
// Create the SQL query for the recordset (appointments).
strSourceFolderUrl = "file://./backofficestorage/" + \
strDomainName + "/" + strLocalPathOfSourceFolder;
strSearchSql = "select ";
strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
strSearchSql = strSearchSql + ", \"DAV:href\"";
strSearchSql = strSearchSql + ", \"DAV:displayname\"";
strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
strSearchSql = strSearchSql + ", \"DAV:iscollection\"";
strSearchSql = strSearchSql + ", \"urn:schemas:contacts:nickname\"";
strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = false";
// TODO
strSearchSql = strSearchSql + " AND \"urn:schemas:contacts:nickname\" = 'Small'";
ModifyObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);
// Sample 3: Modify the name of the "TestFolder" folder.
strLocalPathOfSourceFolder = "MBX/" + strUser + "/Outbox";
// Create the SQL query for the recordset (appointments).
strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;
strSearchSql = "select ";
strSearchSql = strSearchSql + "\"urn:schemas:mailheader:content-class\"";
strSearchSql = strSearchSql + ", \"DAV:href\"";
strSearchSql = strSearchSql + ", \"DAV:displayname\"";
strSearchSql = strSearchSql + ", \"DAV:isfolder\"";
strSearchSql = strSearchSql + ", \"DAV:iscollection\"";
strSearchSql = strSearchSql + ", \"urn:schemas:httpmail:subject\"";
strSearchSql = strSearchSql + " from scope ('shallow traversal of ";
strSearchSql = strSearchSql + "\"" + strSourceFolderUrl + "\"" + "')";
strSearchSql = strSearchSql + " WHERE \"DAV:ishidden\" = false";
strSearchSql = strSearchSql + " AND \"DAV:isfolder\" = true";
// TODO
strSearchSql = strSearchSql + " AND \"DAV:displayname\" = 'TestFolder'";
ModifyObjects(strDomainName, strLocalPathOfSourceFolder, strSearchSql);
}
// Modify objects and specially
// - change folder name
// - modify appointment and contact
void ModifyObjects(_bstr_t strDomainName, _bstr_t strLocalPathOfSourceFolder, _bstr_t strSearchSql)
{
_ConnectionPtr conn(_uuidof(Connection));
_RecordsetPtr Rst(_uuidof(Recordset));
_bstr_t strSourceFolderUrl;
HRESULT hr = S_OK;
try
{
// Set the strURL to the location of the folders.
strSourceFolderUrl = "file://./backofficestorage/" + strDomainName + "/" + strLocalPathOfSourceFolder;
printf("strSourceFolderUrl : %s\n", (char *)strSourceFolderUrl);
// Open the connection.
conn->Provider = "Exoledb.DataSource";
hr = conn->Open(strSourceFolderUrl,"","",0);
if (conn->State == adStateOpen)
printf("Connection Opened!\n");
else
printf("Connection failed!\n");
// Open the recordset.
hr = Rst->Open(strSearchSql,conn->ConnectionString,adOpenForwardOnly,adLockOptimistic,0);
// Test to see if the recordset opened without error.
if (Rst->State == adStateOpen)
printf("Rst Opened Successfully!\n");
else
printf("Rst Opened Failed!\n");
printf("Objects founded # = %d\n", Rst->RecordCount);
// Check to determine if any objects were found.
if (Rst->RecordCount == 0)
{
printf("No object needs to be modified!\n");
return;
}
// Some objects were found.
hr = Rst->MoveFirst();
_bstr_t strResult = "";
while (VARIANT_FALSE == Rst->adoEOF)
{
_bstr_t strObjectUrl;
_bstr_t strContentClass;
bool boolIsCollection;
// Retrieve some properties.
FieldsPtr Flds = Rst->GetFields();
FieldPtr Fld = Flds->GetItem("DAV:href");
strObjectUrl = (_bstr_t)(Fld->Value);
Fld = Flds->GetItem("urn:schemas:mailheader:content-class");
strContentClass = (_bstr_t)(Fld->Value);
Fld = Flds->GetItem("DAV:iscollection");
boolIsCollection = (bool)(Fld->Value);
// printf("Content-clase = %s\n", (char *)strContentClass);
if (boolIsCollection)
{
Fld = Flds->GetItem("DAV:displayname");
printf("Folder : %s\n", (char *)(_bstr_t)(Fld->Value));
_RecordPtr Rec(__uuidof(Record));
_bstr_t strFolderNewName = "ModifiedName";
// Open the record.
hr = Rec->Open((_variant_t)strObjectUrl,
conn->ConnectionString,
adModeReadWrite,
adFailIfNotExists,
adOpenSource,
bstr_t(), bstr_t());
// Use move to change the folder name.
Rec->MoveRecord(strObjectUrl,
strSourceFolderUrl + "/" + strFolderNewName,
"", "",
adMoveOverWrite,
false);
// Close the record.
Rec->Close();
// Clean up.
Rec = NULL;
}
else{
if (wcsicmp(strContentClass, (_bstr_t)"urn:content-classes:message") == 0)
{
// You will not modify the message, but just check some properties for the moment. // TODO
IMessagePtr pMsg(__uuidof(Message));
IDataSourcePtr pDsrc;
hr = pMsg->get_DataSource(&pDsrc);
hr = pDsrc->Open((_bstr_t)strObjectUrl,
NULL,
adModeReadWrite,
adFailIfNotExists,
adOpenSource,
bstr_t(), bstr_t());
// Get the date received.
Flds = pMsg->GetFields();
Fld = Flds->GetItem("urn:schemas:httpmail:datereceived");
printf("Message\n");
printf("Sender :%s\n", (char *)(_bstr_t)pMsg->Sender);
printf("TimeReceived :%s\n\n", (char *)(_bstr_t)(Fld->Value));
// Clean up.
pDsrc = NULL;
pMsg = NULL;
}
else if (wcsicmp(strContentClass, (_bstr_t)"urn:content-classes:person") == 0)
{
IPersonPtr pPerson(__uuidof(Person));
IDataSourcePtr pDsrc;
hr = pPerson->get_DataSource(&pDsrc);
hr = pDsrc->Open( (_bstr_t)strObjectUrl,
NULL,
adModeReadWrite,
adFailIfNotExists,
adOpenSource,
bstr_t(), bstr_t());
// Change a property directly.
pPerson->Title = (_bstr_t)"Developer";
// Change a property by using fields.
Flds = pPerson->GetFields();
Fld = Flds->GetItem("urn:schemas:contacts:department");
Fld->Value = (_bstr_t)"New department";
Flds->Update();
// Update the changed properties.
pDsrc->Save();
// Clear the objects.
pDsrc = NULL;
pPerson = NULL;
}
else if (wcsicmp(strContentClass, (_bstr_t)"urn:content-classes:appointment") == 0)
{
IAppointmentPtr pAppt(__uuidof(Appointment));
IDataSourcePtr pDsrc;
hr = pAppt->get_DataSource(&pDsrc);
hr = pDsrc->Open( (_bstr_t)strObjectUrl,
NULL,
adModeReadWrite,
adFailIfNotExists,
adOpenSource,
bstr_t(), bstr_t());
// Change some properties.
pAppt->Subject = (_bstr_t)"New Subject";
pAppt->Location = (_bstr_t)"New Location";
pDsrc->Save();
// Clean up.
pDsrc = NULL;
pAppt = NULL;
}
else
{
printf("Else case = %s\n", (char *)strContentClass);
}
}
Rst->MoveNext();
}
// Close connections.
Rst->Close();
conn->Close();
// Clean up.
Rst = NULL;
conn = NULL;
}
catch(_com_error &e)
{
dump_com_error(e);
}
}
// GetDomainName
//
// Params: [out] BSTR * bstrDomainName
// Output: HRESULT
// Purpose: Retrieve the domain DNS name.
HRESULT GetDomainName(BSTR * bstrDomainName)
{
HRESULT hr = S_OK;
IADsADSystemInfo *pADsys;
hr = CoCreateInstance(CLSID_ADSystemInfo,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsADSystemInfo,
(void**)&pADsys);
hr = pADsys->get_DomainDNSName(bstrDomainName);
if (pADsys)
pADsys->Release();
return hr;
}