MAPI: Outlook Gives Out-of-Memory Error

ID: Q241566


The information in this article applies to:
  • Microsoft Outlook Windows NT client, version 9.0
  • Microsoft Outlook Windows 95/98 client, version 9.0
  • MAPI


SYMPTOMS

On slower computers, if you run the IMAPISession::PrepareForm and IMAPISession::ShowForm functions in a loop to display multiple Outlook forms, it may cause errors. The first call to ShowForm will work. Subsequent calls to ShowForm may display the following error message if you try to add an attachment with drag and drop:

Out of memory or system resources. Close some windows and try again.
See the "More Information" section for sample code that demonstrates this behavior.


CAUSE

A bad reference count causes an internal object creation failure. This returns an error code, which is interpreted as out of memory.


RESOLUTION

When an application invokes ShowForm, the form server for the which the form is registered is loaded. MAPI adds a reference to the form server when it runs the form. When the form is closed, MAPI releases the reference. When there are no references left on the form server, it shuts down.

In this case, IPM.Note is registered to use Outlook.exe as its form server. When you dismiss the displayed message, Outlook begins to shut down. While Outlook is shutting down, it is not in a state where it can accept calls to open a new form. There is a timing issue here: If Outlook does not fully shut down before the next form is invoked, MAPI interprets this as a failure caused by limited memory. However, if Outlook can shut down completely first, the next form will open without a problem.

If an application knows it will be opening multiple forms that use Outlook as their form server, it will want to ensure that Outlook stays in memory continuously while it is displaying forms. One way to do this, demonstrated in the "Workaround" section of this article, is to create an Outlook.Application object. This causes Outlook to load and stay running until the object is released. The application can then create and destroy as many items as it needs and not have the timing problems or the performance hit of Outlook constantly starting and stopping.

If the application only wants to create an Outlook.Application object when Outlook is the registered mail client, check the following registry key:

HKEY_LOCAL_MACHINE\Software\Clients\Mail
If the default value is set to "Microsoft Outlook," Outlook is the application that handles the ShowForm function.


WORKAROUND

Here is sample code which demonstrates the workaround. For sample code that implements OpenDefaultMessageStore and OpenInbox, please see the following article in the Microsoft Knowledge Base:

Q239795 HOWTO: List Messages in the Inbox with MAPI


HRESULT CreateObject(LPOLESTR pszProgID, IDispatch FAR* FAR* ppdisp) 
{ 
    CLSID clsid;                   // CLSID of automation object 
    HRESULT hr; 
    LPUNKNOWN punk = NULL;         // IUnknown of automation object 
    LPDISPATCH pdisp = NULL;       // IDispatch of automation object 
     
    *ppdisp = NULL; 
     
    // Retrieve CLSID from the progID that the user specified 
    hr = CLSIDFromProgID(pszProgID, &clsid); 
    if (FAILED(hr)) 
        goto error; 
     
    // Create an instance of the automation object and ask for the IDispatch interface 
    hr = CoCreateInstance(clsid, NULL, CLSCTX_SERVER,  
                          IID_IUnknown, (void FAR* FAR*)&punk); 
    if (FAILED(hr)) 
        goto error; 
                    
    hr = punk->QueryInterface(IID_IDispatch, (void FAR* FAR*)&pdisp); 
    if (FAILED(hr)) 
        goto error; 
 
    *ppdisp = pdisp; 
    punk->Release(); 
    return NOERROR; 
      
error: 
    if (punk) punk->Release(); 
    if (pdisp) pdisp->Release(); 
    return hr; 
}   

void main(void)
{
	HRESULT			hRes;
	LPMAPISESSION	lpMAPISession = NULL;
	LPMDB			lpMDB = NULL;
	LPMAPIFOLDER	lpInboxFolder = NULL;

	LPMESSAGE		lpMessage = NULL;
	ULONG			ulToken = 0;	
	int i = 0;
	
	hRes = MAPIInitialize(NULL);
	if (!CHECKHRES(hRes)) goto Cleanup;
	
	hRes = MAPILogonEx(0,
		NULL,
		NULL,
		MAPI_LOGON_UI ||
		MAPI_NEW_SESSION ,
		&lpMAPISession);
	if (!CHECKHRES(hRes)) goto Cleanup;
	
	//some function to open a message store	
	hRes = OpenDefaultMessageStore(
		lpMAPISession,
		&lpMDB);
	if (!CHECKHRES(hRes)) goto Cleanup;
	
	//some function to open the inbox
	hRes = OpenInbox(
		lpMDB,
		&lpInboxFolder);
	if (!CHECKHRES(hRes)) goto Cleanup;

	LPDISPATCH pOutlook; 
    hRes = CreateObject(OLESTR("Outlook.Application"), &pOutlook);
	if (!CHECKHRES(hRes)) goto Cleanup;
	//First Message
	for (i = 1 ; i<=20 ; i++)
	{
		hRes = lpInboxFolder->CreateMessage(
			NULL,
			NULL,
			&lpMessage);
		if (!CHECKHRES(hRes)) goto Cleanup;
		
		hRes = lpMAPISession->PrepareForm(
			NULL,
			lpMessage,
			&ulToken);
		if (!CHECKHRES(hRes)) goto Cleanup;
		
		UlRelease(lpMessage);
		
		hRes = lpMAPISession->ShowForm(
			NULL,
			lpMDB,
			lpInboxFolder,
			NULL,
			ulToken,
			NULL,
			MAPI_NEW_MESSAGE,
			NULL,
			MSGFLAG_UNSENT | MSGFLAG_READ,
			NULL,
			"IPM.NOTE");
		if (hRes == MAPI_E_USER_CANCEL) hRes = S_OK;
		if (!CHECKHRES(hRes)) goto Cleanup;
	}
	pOutlook->Release(); 

	//Always clean up your memory here!
Cleanup:
	UlRelease(lpInboxFolder);
	UlRelease(lpMDB);
	UlRelease(lpMAPISession);
	MAPIUninitialize();
	if (FAILED(hRes))
	{
		printf("Failed with hRes of %x\n",hRes);		
	}
	printf("Type something to quit:");
	while (!_kbhit()){}
	_getch();
} 


STATUS

Microsoft has confirmed this to be a problem in the Microsoft products listed at the beginning of this article.


MORE INFORMATION

In the following code fragment, the ShowForm function may cause an out-of-memory error while running multiple times in the loop. The error happens most often when attachments are added to successive messages.


	.....
        hRes = MAPIInitialize(NULL);
	if (!CHECKHRES(hRes)) goto Cleanup;
	
	hRes = MAPILogonEx(0,
		NULL,
		NULL,
		MAPI_LOGON_UI ||
		MAPI_NEW_SESSION ,
		&lpMAPISession);
	if (!CHECKHRES(hRes)) goto Cleanup;

	//some function to open a message store	
	hRes = OpenDefaultMessageStore(
		lpMAPISession,
		&lpMDB);
	if (!CHECKHRES(hRes)) goto Cleanup;

	//some function to open the inbox
	hRes = OpenInbox(
		lpMDB,
		&lpInboxFolder);
	if (!CHECKHRES(hRes)) goto Cleanup;

	//Create twenty messages
	for (i = 1 ; i<=20 ; i++)
	{
		hRes = lpInboxFolder->CreateMessage(
			NULL,
			NULL,
			&lpMessage);
		if (!CHECKHRES(hRes)) goto Cleanup;
		
		hRes = lpMAPISession->PrepareForm(
			NULL,
			lpMessage,
			&ulToken);
		if (!CHECKHRES(hRes)) goto Cleanup;
		
		UlRelease(lpMessage);
		
		hRes = lpMAPISession->ShowForm(
			NULL,
			lpMDB,
			lpInboxFolder,
			NULL,
			ulToken,
			NULL,
			MAPI_NEW_MESSAGE,
			NULL,
			MSGFLAG_UNSENT | MSGFLAG_READ,
			NULL,
			"IPM.NOTE");
		
		if (hRes == MAPI_E_USER_CANCEL) hRes = S_OK;
		if (!CHECKHRES(hRes)) goto Cleanup;
	}

	//Always clean up your memory here!
Cleanup:
	....
 

Additional query words: sgriffin

Keywords : kbMsg kbOutlook
Version : WINDOWS:9.0
Platform : WINDOWS
Issue type : kbbug


Last Reviewed: November 18, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.