Home All Groups Group Topic Archive Search About

MAPI profiles and corrupt registry

Author
4 Apr 2007 2:44 PM
Vladimir Werskov
Hello to all.

We are facing a very strange problem with Extended MAPI. We have a multi
threaded Windows service (ATL). The service is able to connect to all
mailboxes in the organization. For this a new MAPI profile is created
(permanent) with a unique name. The profile is used to connect to the
mailbox, do the action on the mailbox and then logoff is called. The MAPI
profile is immediately deleted after the logoff.

This is working correctly, however after some time (weekly or monthly)
strange thing happens: the service is not able to log on to any mailbox and
the registry key (the service runs under a specific account)

HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging
Subsystem\Profiles

can't be opened anymore. It is not possible to open or delete the registry
key. I have searched for an open handle among the running processes for this
registry key, but there was none. The registry key can only be deleted after
a reboot.
After the reboot the same situation can be reproduced at least once a month.
I must add that the number of profiles created/deleted per day can exceed the
number 100000.
When the registry key gets corrupted, it is not possible to call
MAPIInitialize - it returns MAPI_E_NOT_INITIALIZED.
The MAPI32.dll is the one from the Exchange System Manager. No Outlook is
installed.

Is there any known issue with this registry key?
Is there a way to restart the MAPI subsystem without restarting the server?

Thank you very much.

Author
5 Apr 2007 6:11 AM
Dmitry Streblechenko
Is your code executed on the saee thread? If yes, why do you need to call
MAPIInitialize multiple times?
Did you monitor the number of handles and memory usage of the process?
Sounds llike you have a reference leak somewhere in you code...

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy  - Outlook, CDO
and MAPI Developer Tool

Show quote
"Vladimir Werskov" <Vladimir Wers***@discussions.microsoft.com> wrote in
message news:A5189D9E-2533-4839-ACF7-0C334A27D5E6@microsoft.com...
> Hello to all.
>
> We are facing a very strange problem with Extended MAPI. We have a multi
> threaded Windows service (ATL). The service is able to connect to all
> mailboxes in the organization. For this a new MAPI profile is created
> (permanent) with a unique name. The profile is used to connect to the
> mailbox, do the action on the mailbox and then logoff is called. The MAPI
> profile is immediately deleted after the logoff.
>
> This is working correctly, however after some time (weekly or monthly)
> strange thing happens: the service is not able to log on to any mailbox
> and
> the registry key (the service runs under a specific account)
>
> HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging
> Subsystem\Profiles
>
> can't be opened anymore. It is not possible to open or delete the registry
> key. I have searched for an open handle among the running processes for
> this
> registry key, but there was none. The registry key can only be deleted
> after
> a reboot.
> After the reboot the same situation can be reproduced at least once a
> month.
> I must add that the number of profiles created/deleted per day can exceed
> the
> number 100000.
> When the registry key gets corrupted, it is not possible to call
> MAPIInitialize - it returns MAPI_E_NOT_INITIALIZED.
> The MAPI32.dll is the one from the Exchange System Manager. No Outlook is
> installed.
>
> Is there any known issue with this registry key?
> Is there a way to restart the MAPI subsystem without restarting the
> server?
>
> Thank you very much.
>
Author
5 Apr 2007 7:14 AM
Vladimir Werskov
Hello,

first, thanks for the answer.
To make things clear:

When the service starts, it calls MAPIInitialize on the main thread. When
the service is shut down it calls MAPIUninitialize. This is needed to keep
the MAPI subsystem alive until my threads are working.

In the service's PreMessageLoop (ATL 7) the MAPI_Initialize method is called.

bool CServiceModule::MAPI_Initialize()
{
        HRESULT hr = S_OK;
        MAPIINIT_0 MAPIINIT = {0, MAPI_MULTITHREAD_NOTIFICATIONS | MAPI_NT_SERVICE
| MAPI_NO_COINIT};

        hr = MAPIInitialize(&MAPIINIT);
        if (FAILED(hr))
        {
            LogEvent(_T("Error: MAPI_Initialize >> %08X\n"), hr);
            return false;
        }
        return true;
}

Then in the PostMessageLoop the MAPIUninitialize is called to release the
last reference to MAPI.

When one of the service interfaces is called, it actually creates a new COM
object (implemented by a COM DLL), which calls MAPIInitialize (same
parameters as above) in the constructor. The COM objects are always used by
only one thread, but multiple threads can create their own objects. In the
destructor of the COM object, the MAPIUninitialize is called.

On the target systems, the service is restarted at least once a day - in
this case the service stops without errors. But the registry still gets
corrupted. So the corruption occurs independently of whether the service is
running or not.
There is no other application which is using MAPI so after the service
terminates, the resources (also the possible leaked ones) should be released,
right?
I have at least 5 years of experience with MAPI programming, but this is
something which makes me crazy. No matter how you fine tune your
applications, guard them by external applications, it gets stuck and the
whole system must be restarted. If there whould be a workaround or
possibility to delete the corrupted registry key - i would be happy.

Show quote
"Dmitry Streblechenko" wrote:

> Is your code executed on the saee thread? If yes, why do you need to call
> MAPIInitialize multiple times?
> Did you monitor the number of handles and memory usage of the process?
> Sounds llike you have a reference leak somewhere in you code...
>
> Dmitry Streblechenko (MVP)
> http://www.dimastr.com/
> OutlookSpy  - Outlook, CDO
> and MAPI Developer Tool
Author
5 Apr 2007 9:19 PM
Dmitry Streblechenko
Hmmm... I don't know. I can omly suggest the standard technique of
commenting your code and bringing it back until the problem manifetss
itself.

Dmitry Streblechenko (MVP)
http://www.dimastr.com/
OutlookSpy  - Outlook, CDO
and MAPI Developer Tool

Show quote
"Vladimir Werskov" <Vladimir Wers***@discussions.microsoft.com> wrote in
message news:ECF2F526-43E7-48F9-A548-E6DDBFD97BBA@microsoft.com...
> Hello,
>
> first, thanks for the answer.
> To make things clear:
>
> When the service starts, it calls MAPIInitialize on the main thread. When
> the service is shut down it calls MAPIUninitialize. This is needed to keep
> the MAPI subsystem alive until my threads are working.
>
> In the service's PreMessageLoop (ATL 7) the MAPI_Initialize method is
> called.
>
> bool CServiceModule::MAPI_Initialize()
> {
> HRESULT hr = S_OK;
> MAPIINIT_0 MAPIINIT = {0, MAPI_MULTITHREAD_NOTIFICATIONS | MAPI_NT_SERVICE
> | MAPI_NO_COINIT};
>
> hr = MAPIInitialize(&MAPIINIT);
> if (FAILED(hr))
> {
> LogEvent(_T("Error: MAPI_Initialize >> %08X\n"), hr);
> return false;
> }
> return true;
> }
>
> Then in the PostMessageLoop the MAPIUninitialize is called to release the
> last reference to MAPI.
>
> When one of the service interfaces is called, it actually creates a new
> COM
> object (implemented by a COM DLL), which calls MAPIInitialize (same
> parameters as above) in the constructor. The COM objects are always used
> by
> only one thread, but multiple threads can create their own objects. In the
> destructor of the COM object, the MAPIUninitialize is called.
>
> On the target systems, the service is restarted at least once a day - in
> this case the service stops without errors. But the registry still gets
> corrupted. So the corruption occurs independently of whether the service
> is
> running or not.
> There is no other application which is using MAPI so after the service
> terminates, the resources (also the possible leaked ones) should be
> released,
> right?
> I have at least 5 years of experience with MAPI programming, but this is
> something which makes me crazy. No matter how you fine tune your
> applications, guard them by external applications, it gets stuck and the
> whole system must be restarted. If there whould be a workaround or
> possibility to delete the corrupted registry key - i would be happy.
>
> "Dmitry Streblechenko" wrote:
>
>> Is your code executed on the saee thread? If yes, why do you need to call
>> MAPIInitialize multiple times?
>> Did you monitor the number of handles and memory usage of the process?
>> Sounds llike you have a reference leak somewhere in you code...
>>
>> Dmitry Streblechenko (MVP)
>> http://www.dimastr.com/
>> OutlookSpy  - Outlook, CDO
>> and MAPI Developer Tool
>
Author
8 Apr 2007 2:45 AM
Dave Goldman [MSFT]
I can tell you that you aren't going to want to create 10000 profiles on the
system as you will get to a point where the mapi subsystem will fail. As a
suggestion I would also set the profile to deferred delete and not delete
them right away as this is going to access that registry key when you call
Delete Profile. As with any multi-thread program you can run in to areas
where one thread might be releasing some resources that are needed by
another. Are you using debug asserts in your debug build to try and track
this down?

Are you sure that one of your other threads is not disposing its objects and
calling mapi uninitialize on you? I would insert some code around the areas
that are creating and deleting the profiles and print out an failed
hresults, as well as you might want to use some critical sections if you are
not already.

There is no problem when you call MAPIInitialize on the main thread or when
you shut it down, this should be like this. You might want to take a look at
this as well to see if this helps: http://support.microsoft.com/kb/891425.
MAPI stores "instance data" for each security context that calls
MAPIInitialize. The information includes the heap handles, shared sections
for interacting with other processes using the same security context, etc.
Instance data lives in a structure that is keyed to a hash of the current
security context's SID. So, if you create a MAPI object under one security
context and release it under another, MAPI either a) fails to find the
instance data and crashes, or b) frees the object from the wrong heap and
corrupts the heap. How this instance data is affected by impersonation was
also involved in the Deleted Profile issue. For more information on the
Deleted Profile issue see this blog:
http://blogs.msdn.com/stephen_griffin/archive/2004/08/20/217919.aspx.

--
This posting is provided "AS IS" with no warranties, and confers no rights.

Dgoldman
http://blogs.msdn.com/dgoldman
Download OABInteg from here:
http://gotdotnet.com/Community/UserSamples/Download.aspx?SampleGuid=A2338E73-F521-4071-9B1D-AAF49C346ACD


Show quote
"Dmitry Streblechenko" <dmi***@dimastr.com> wrote in message
news:eS%23krj0dHHA.596@TK2MSFTNGP06.phx.gbl...
> Is your code executed on the saee thread? If yes, why do you need to call
> MAPIInitialize multiple times?
> Did you monitor the number of handles and memory usage of the process?
> Sounds llike you have a reference leak somewhere in you code...
>
> Dmitry Streblechenko (MVP)
> http://www.dimastr.com/
> OutlookSpy  - Outlook, CDO
> and MAPI Developer Tool
>
> "Vladimir Werskov" <Vladimir Wers***@discussions.microsoft.com> wrote in
> message news:A5189D9E-2533-4839-ACF7-0C334A27D5E6@microsoft.com...
>> Hello to all.
>>
>> We are facing a very strange problem with Extended MAPI. We have a multi
>> threaded Windows service (ATL). The service is able to connect to all
>> mailboxes in the organization. For this a new MAPI profile is created
>> (permanent) with a unique name. The profile is used to connect to the
>> mailbox, do the action on the mailbox and then logoff is called. The MAPI
>> profile is immediately deleted after the logoff.
>>
>> This is working correctly, however after some time (weekly or monthly)
>> strange thing happens: the service is not able to log on to any mailbox
>> and
>> the registry key (the service runs under a specific account)
>>
>> HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging
>> Subsystem\Profiles
>>
>> can't be opened anymore. It is not possible to open or delete the
>> registry
>> key. I have searched for an open handle among the running processes for
>> this
>> registry key, but there was none. The registry key can only be deleted
>> after
>> a reboot.
>> After the reboot the same situation can be reproduced at least once a
>> month.
>> I must add that the number of profiles created/deleted per day can exceed
>> the
>> number 100000.
>> When the registry key gets corrupted, it is not possible to call
>> MAPIInitialize - it returns MAPI_E_NOT_INITIALIZED.
>> The MAPI32.dll is the one from the Exchange System Manager. No Outlook is
>> installed.
>>
>> Is there any known issue with this registry key?
>> Is there a way to restart the MAPI subsystem without restarting the
>> server?
>>
>> Thank you very much.
>>
>
>
Author
10 Apr 2007 4:28 PM
Vladimir Werskov
Thank you for your useful suggestions!

I will definitely try the MAPI_TEMPORARY_PROFILES flag.

I do not want to steal your time anymore, so only for completeness:
- there are no 10000 simultaneously created profiles on the system. The
profile is created, logged on to.
Then i perform the necessary MAPI function. After this has finished, the
session is logged off and the profile is deleted.
So the number of simultaneously created profiles depends on the number of
request on the service. Once the task is finished,
everything is cleaned up.
- what do you mean by "deferred delete"? I do not remove the profile
immediately - only after it is logged off
- to the multi threading issues: the client of the service is always
creating a new thread. This thread then creates a COM object
from the service. Each COM object is generating a unique profile name. Each
COM object has it's own resources. The same object is never
used by another thread - only the creator. I am tracking each object and
each call - printing out using OutputDebugString the THREADID
and the object's 'this' address. This was fine.
- i am using critical sections in profile creating and deletion. Do you
suggest that i should lock the MAPIInitialize/MAPIUninitialize too?

What i will try is this:
- monitor the MAPIInitialize/MAPIUninitialize for each request/thread
- log the result code from DeleteProfile if not S_OK

What is still open is how it is possible that after the service has
terminated, the registry key is not accessible.
Should the OS not free up the resources after the process terminates?

Show quote
"Dave Goldman [MSFT]" wrote:

> I can tell you that you aren't going to want to create 10000 profiles on the
> system as you will get to a point where the mapi subsystem will fail. As a
> suggestion I would also set the profile to deferred delete and not delete
> them right away as this is going to access that registry key when you call
> Delete Profile. As with any multi-thread program you can run in to areas
> where one thread might be releasing some resources that are needed by
> another. Are you using debug asserts in your debug build to try and track
> this down?
>
> Are you sure that one of your other threads is not disposing its objects and
> calling mapi uninitialize on you? I would insert some code around the areas
> that are creating and deleting the profiles and print out an failed
> hresults, as well as you might want to use some critical sections if you are
> not already.
>
> There is no problem when you call MAPIInitialize on the main thread or when
> you shut it down, this should be like this. You might want to take a look at
> this as well to see if this helps: http://support.microsoft.com/kb/891425.
> MAPI stores "instance data" for each security context that calls
> MAPIInitialize. The information includes the heap handles, shared sections
> for interacting with other processes using the same security context, etc.
> Instance data lives in a structure that is keyed to a hash of the current
> security context's SID. So, if you create a MAPI object under one security
> context and release it under another, MAPI either a) fails to find the
> instance data and crashes, or b) frees the object from the wrong heap and
> corrupts the heap. How this instance data is affected by impersonation was
> also involved in the Deleted Profile issue. For more information on the
> Deleted Profile issue see this blog:
> http://blogs.msdn.com/stephen_griffin/archive/2004/08/20/217919.aspx.
>
> --
> This posting is provided "AS IS" with no warranties, and confers no rights.
>
> Dgoldman
> http://blogs.msdn.com/dgoldman
> Download OABInteg from here:
> http://gotdotnet.com/Community/UserSamples/Download.aspx?SampleGuid=A2338E73-F521-4071-9B1D-AAF49C346ACD
>
>
Author
10 Apr 2007 5:15 PM
Dave Goldman [MSFT]
It is very possible that the way the resources are being terminated are
doing something to the registry. It could also be possible that the way we
are accessing the registry is not being fully released. As a suggestion you
can try using regmon while you are running your progam and then right before
the failure look to see who is touching the registry. You can then try to
corrolate some time frame as to the last time your program touched the
registry and the time of the corruption. Perhaps the application is failing
somewhere or hitting an exception that is being eaten and not handled
properly, thus you never get to see it.

How many simultaneously profiles are created at the same time? The
IProfAdmin::DeleteProfile method deletes a profile. If the profile to delete
is in use when DeleteProfile is called, DeleteProfile returns S_OK but does
*not* delete the profile immediately. Instead, DeleteProfile marks the
profile for deletion and deletes it after it is no longer being used, when
all of its active sessions have ended.

I would put critical sections around the Initalize and UnInitialize just to
make sure that its not being called by another thread.

--
This posting is provided "AS IS" with no warranties, and confers no rights.

Dgoldman
http://blogs.msdn.com/dgoldman
Download OABInteg from here:
http://gotdotnet.com/Community/UserSamples/Download.aspx?SampleGuid=A2338E73-F521-4071-9B1D-AAF49C346ACD


Show quote
"Vladimir Werskov" <VladimirWers***@discussions.microsoft.com> wrote in
message news:1E4CF5C2-A4CE-4767-A6D7-03036EC6627B@microsoft.com...
> Thank you for your useful suggestions!
>
> I will definitely try the MAPI_TEMPORARY_PROFILES flag.
>
> I do not want to steal your time anymore, so only for completeness:
> - there are no 10000 simultaneously created profiles on the system. The
> profile is created, logged on to.
> Then i perform the necessary MAPI function. After this has finished, the
> session is logged off and the profile is deleted.
> So the number of simultaneously created profiles depends on the number of
> request on the service. Once the task is finished,
> everything is cleaned up.
> - what do you mean by "deferred delete"? I do not remove the profile
> immediately - only after it is logged off
> - to the multi threading issues: the client of the service is always
> creating a new thread. This thread then creates a COM object
> from the service. Each COM object is generating a unique profile name.
> Each
> COM object has it's own resources. The same object is never
> used by another thread - only the creator. I am tracking each object and
> each call - printing out using OutputDebugString the THREADID
> and the object's 'this' address. This was fine.
> - i am using critical sections in profile creating and deletion. Do you
> suggest that i should lock the MAPIInitialize/MAPIUninitialize too?
>
> What i will try is this:
> - monitor the MAPIInitialize/MAPIUninitialize for each request/thread
> - log the result code from DeleteProfile if not S_OK
>
> What is still open is how it is possible that after the service has
> terminated, the registry key is not accessible.
> Should the OS not free up the resources after the process terminates?
>
> "Dave Goldman [MSFT]" wrote:
>
>> I can tell you that you aren't going to want to create 10000 profiles on
>> the
>> system as you will get to a point where the mapi subsystem will fail. As
>> a
>> suggestion I would also set the profile to deferred delete and not delete
>> them right away as this is going to access that registry key when you
>> call
>> Delete Profile. As with any multi-thread program you can run in to areas
>> where one thread might be releasing some resources that are needed by
>> another. Are you using debug asserts in your debug build to try and track
>> this down?
>>
>> Are you sure that one of your other threads is not disposing its objects
>> and
>> calling mapi uninitialize on you? I would insert some code around the
>> areas
>> that are creating and deleting the profiles and print out an failed
>> hresults, as well as you might want to use some critical sections if you
>> are
>> not already.
>>
>> There is no problem when you call MAPIInitialize on the main thread or
>> when
>> you shut it down, this should be like this. You might want to take a look
>> at
>> this as well to see if this helps:
>> http://support.microsoft.com/kb/891425.
>> MAPI stores "instance data" for each security context that calls
>> MAPIInitialize. The information includes the heap handles, shared
>> sections
>> for interacting with other processes using the same security context,
>> etc.
>> Instance data lives in a structure that is keyed to a hash of the current
>> security context's SID. So, if you create a MAPI object under one
>> security
>> context and release it under another, MAPI either a) fails to find the
>> instance data and crashes, or b) frees the object from the wrong heap and
>> corrupts the heap. How this instance data is affected by impersonation
>> was
>> also involved in the Deleted Profile issue. For more information on the
>> Deleted Profile issue see this blog:
>> http://blogs.msdn.com/stephen_griffin/archive/2004/08/20/217919.aspx.
>>
>> --
>> This posting is provided "AS IS" with no warranties, and confers no
>> rights.
>>
>> Dgoldman
>> http://blogs.msdn.com/dgoldman
>> Download OABInteg from here:
>> http://gotdotnet.com/Community/UserSamples/Download.aspx?SampleGuid=A2338E73-F521-4071-9B1D-AAF49C346ACD
>>
>>
>

AddThis Social Bookmark Button