Emptying the Deleted Items Folder with OLEDB

Emptying the Deleted Items Folder with OLEDB

This content is no longer actively maintained. It is provided as is, for anyone who may still be using these technologies, with no warranties or claims of accuracy with regard to the most recent product version or service release.

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.

// Empty the Deleted Items Folder with OLEDB
// This sample demonstrates how to delete mail items in the Deleted Items folder
// using OLEDB.

#define DBINITCONSTANTS
#define NUMROWS_CHUNK  5
#define INITGUID
#include <windows.h>
#include <stdio.h>
#include <oledb.h>
#include <oledberr.h>

int main(int argc, char** argv)
{
   HRESULT hr = NULL;

   if (argc !=2)
   {
      printf("Usage: EmptyDeletedItems\r\n");
      printf("Example: EmptyDeletedItems \"file://./backofficestorage/mydomain.contoso.com/MBX/User1/Deleted Items\"\n");
      exit(0);
   }

   wchar_t* folderURL = NULL;
   size_t size;

   // Note: It is recommended that all input parameters be validated when they are
   // first obtained from the user or user interface.
   size = mbstowcs(NULL,argv[1],0);
   folderURL = (wchar_t*)malloc(size * sizeof(wchar_t*) + 1);
   mbstowcs(folderURL,argv[1],size+1);

   printf("folderURL: %ls\n", folderURL);
   BSTR bstrFolderURL = SysAllocString(folderURL);
   printf("Folder URL: %S\n", bstrFolderURL);

   wchar_t* strURL = NULL;
   wchar_t* str1 = L"Select * from scope('shallow traversal of \"";
   wchar_t* str2 = L"\"')";
   size_t size2, size3;
   size2 = mbstowcs(NULL, "Select * from scope('shallow traversal of \"", 0);
   size3 = mbstowcs(NULL, "\')", 0);
   strURL = (wchar_t*)malloc(size * sizeof(wchar_t*) + size2 + size3 + 1);
   wcscpy(strURL, str1);
   wcscat(strURL, folderURL);
   wcscat(strURL, str2);
   printf("strURL: %ls\n", strURL);

   IDBInitialize *pIDBInitialize;

   // Database property variables
   const ULONG nProps = 4;
   IDBProperties *pIDBProperties;
   DBPROP        InitProp[nProps];
   DBPROPSET     rgInitPropSet;

   // Session variables
   IDBCreateSession *pIDBCreateSession;

   // Command variables
   IDBCreateCommand *pIDBCreateCommand;
   ICommandText     *pICommandText;

   LONG      cRowsAffected;

   // Rowset variables
   IRowset *pIRowset;
   IRowsetChange *pIRowsetChange;

   // Rows fetched
   ULONG cRowsObtained ;

   // Rows handle
   HROW  rghRows[NUMROWS_CHUNK] ;

   // Pointer to the row
   HROW *pRows = &rghRows[0];

   DBROWSTATUS *rgRowStatus = NULL;

   CLSID CLSID_EXOLEDB;
   int MsgCount = 0;

   // Initialize OLE and set up the DLLs.
   CoInitialize(NULL);

   // Create an instance of the Exchange OLEDB provider.
   // Request one of the instances, such as IDBInitialize or IDBProperties.

   hr = CLSIDFromProgID(OLESTR("Exoledb.DataSource"), &CLSID_EXOLEDB);
   if (FAILED(hr))
   {
      printf("CLSIDFromProgID failed\n");
      return (E_FAIL);
   }

   hr = CoCreateInstance(CLSID_EXOLEDB,
                    NULL,
                    CLSCTX_INPROC_SERVER,
                    IID_IDBInitialize,
                    (void**)&pIDBInitialize);

   if(pIDBInitialize == NULL)
   {
      printf("CoCreateInstance of Provider failed\n");
      return (E_FAIL);
   }

   // Get or set the property data source
   // Total of four properties
   // Level of prompting you prefer
   // Data source name
   // User ID
   // Password
   // Initialize common property options
   for (ULONG i=0; i<nProps; i++)
   {
      VariantInit(&InitProp[i].vValue);
      InitProp[i].dwOptions = DBPROPOPTIONS_REQUIRED;
      InitProp[i].colid = DB_NULLID;
   }

   // Set the level of prompting.
   InitProp[0].dwPropertyID = DBPROP_INIT_PROMPT;
   InitProp[0].vValue.vt = VT_I2;
   InitProp[0].vValue.intVal = DBPROMPT_NOPROMPT;

   // Data source name
   InitProp[1].dwPropertyID = DBPROP_INIT_DATASOURCE;
   InitProp[1].vValue.vt = VT_BSTR;
   InitProp[1].vValue.bstrVal = bstrFolderURL;

   // User ID
   InitProp[2].dwPropertyID = DBPROP_AUTH_USERID;
   InitProp[2].vValue.vt = VT_BSTR;
   InitProp[2].vValue.bstrVal = SysAllocString(OLESTR(""));

   // Password
   InitProp[3].dwPropertyID = DBPROP_AUTH_PASSWORD;
   InitProp[3].vValue.vt = VT_BSTR;
   InitProp[3].vValue.bstrVal = SysAllocString(OLESTR(""));

   rgInitPropSet.guidPropertySet = DBPROPSET_DBINIT;
   rgInitPropSet.rgProperties = InitProp;
   rgInitPropSet.cProperties = nProps;

   // Set the initialization properties.
   // Query the IDBProperties interface first.
   hr = pIDBInitialize->QueryInterface(IID_IDBProperties,
                              (void**)&pIDBProperties);
   if( FAILED(hr))
   {
      printf("Query of IDBProperties interface failed\n");
      return E_FAIL;
   }

   hr = pIDBProperties->SetProperties(1,
                              &rgInitPropSet);
   if( FAILED(hr))
   {
      printf("Set IDBProperties failed\n");
      return E_FAIL;
   }

   // Setting of properties was successful.
   SysFreeString(InitProp[1].vValue.bstrVal);
   SysFreeString(InitProp[2].vValue.bstrVal);
   SysFreeString(InitProp[3].vValue.bstrVal);

   // Release the properties.
   pIDBProperties->Release();

   // Call IDBInitialize::Initilize() to get the data source.
   hr = pIDBInitialize->Initialize();
   if(FAILED(hr))
   {
      printf("IDBInitialize failed\n");
      return E_FAIL;
   }

   // QI IDBCreateSession
   hr = pIDBInitialize->QueryInterface(IID_IDBCreateSession,
                              (void **)&pIDBCreateSession);

   if( FAILED(hr))
   {
      printf("Query IDBCreateSession failed\n");
      return E_FAIL;
   }

   // Create the session, Session object: IDBCreateCommand::CreateCommand.
   hr = pIDBCreateSession->CreateSession(NULL,
                                IID_IDBCreateCommand,
                                (IUnknown**) &pIDBCreateCommand);
   // Release the session.
   pIDBCreateSession->Release();

   if( FAILED(hr))
   {
      printf("CreateSession failed\n");
      return E_FAIL;
   }

   // Create the command object.
   hr = pIDBCreateCommand->CreateCommand(NULL,
                                IID_ICommandText,
                                (IUnknown**)&pICommandText);

   pIDBCreateCommand->Release();

   if( FAILED(hr))
   {
      printf("CreateCommand failed");
      return E_FAIL;
   }

   // ICommandText::SetCommandText()
   hr = pICommandText->SetCommandText(DBGUID_DBSQL,
                              strURL);

   if( FAILED(hr))
   {
      printf("set CommandText failed");
      return E_FAIL;
   }

   // ICommand::Execute() to retrieve the rowset.
   hr = pICommandText->Execute(NULL,
                              IID_IRowset,
                        NULL,
                        &cRowsAffected,
                        (IUnknown**)&pIRowset);

   pICommandText->Release();

   if(FAILED(hr))
   {
      printf("Exe CommandText failed\n");
      return E_FAIL;
   }

   // Query IRowsetChange to delete rows.
   hr = pIRowset->QueryInterface(IID_IRowsetChange,
                         (void**)&pIRowsetChange);
   if( FAILED(hr))
   {
      printf("Query IRowsetChange failed\n");
      return E_FAIL;
   }

   // Move through the rowset using GetNextRow() to retrieve the handles
   // to the next row.
   while(TRUE)
   {
      pIRowset ->GetNextRows(

         // Reserved
         0,

         // cRowsToSkip
         0,
         NUMROWS_CHUNK,
         &cRowsObtained,

         // Filled in w/row handle
         &pRows
         );

      // Completed. There are no more rows left to get.
      if(cRowsObtained == 0)
         break;

      MsgCount += cRowsObtained;

      rgRowStatus = new DBROWSTATUS[cRowsObtained];

      // Delete messages.
      pIRowsetChange->DeleteRows(DB_NULL_HCHAPTER,
                           cRowsObtained,
                           rghRows,
                           rgRowStatus);

      // Release the row handles.
      pIRowset->ReleaseRows(cRowsObtained, rghRows, NULL, NULL, NULL);

      delete [] rgRowStatus;

   }// End of while
   printf("\nNumber of items(messages) deleted from Deleted Items Folder: %d\n", MsgCount);

   // Release IRowsetChange
   pIRowsetChange->Release();

   SysFreeString(folderURL);
   SysFreeString(strURL);
   CoUninitialize();
   return NOERROR;
}

Send us your feedback about the Microsoft Exchange Server 2003 SDK.

Build: June 2007 (2007.618.1)

© 2003-2006 Microsoft Corporation. All rights reserved. Terms of use.