windows-nt/Source/XPSP1/NT/windows/winstate/doc/email/registry leak.htm
2020-09-26 16:20:57 +08:00

231 lines
9.5 KiB
HTML
Raw Permalink Blame History

<html xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
<meta name=ProgId content=Word.Document>
<meta name=Generator content="Microsoft Word 9">
<meta name=Originator content="Microsoft Word 9">
<link rel=File-List href="./registry%20leak_files/filelist.xml">
<link rel=Edit-Time-Data href="./registry%20leak_files/editdata.mso">
<link rel=OLE-Object-Data href="./registry%20leak_files/oledata.mso">
<!--[if !mso]>
<style>
v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style>
<![endif]-->
<title>Profile Registry Leak</title>
<!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Author>Alex Armanasu</o:Author>
<o:Template>Normal</o:Template>
<o:LastAuthor>Alex Armanasu</o:LastAuthor>
<o:Revision>4</o:Revision>
<o:TotalTime>31</o:TotalTime>
<o:Created>2000-02-04T02:52:00Z</o:Created>
<o:LastSaved>2000-02-04T03:23:00Z</o:LastSaved>
<o:Pages>1</o:Pages>
<o:Company>Sarut</o:Company>
<o:Lines>1</o:Lines>
<o:Paragraphs>1</o:Paragraphs>
<o:Version>9.2720</o:Version>
</o:DocumentProperties>
</xml><![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{font-family:Courier;
panose-1:0 0 0 0 0 0 0 0 0 0;
mso-font-charset:0;
mso-generic-font-family:modern;
mso-font-format:other;
mso-font-pitch:fixed;
mso-font-signature:3 0 0 0 1 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
p.Paragraph, li.Paragraph, div.Paragraph
{mso-style-name:Paragraph;
margin-top:3.0pt;
margin-right:0in;
margin-bottom:3.0pt;
margin-left:0in;
text-indent:.5in;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";}
p.Code, li.Code, div.Code
{mso-style-name:Code;
margin-top:0in;
margin-right:0in;
margin-bottom:0in;
margin-left:1.0in;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
mso-layout-grid-align:none;
text-autospace:none;
font-size:10.0pt;
font-family:Courier;
mso-fareast-font-family:"Times New Roman";
mso-bidi-font-family:Arial;}
@page Section1
{size:8.5in 11.0in;
margin:1.0in 1.25in 1.0in 1.25in;
mso-header-margin:.5in;
mso-footer-margin:.5in;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style>
</head>
<body lang=EN-US style='tab-interval:.5in'>
<div class=Section1>
<p class=MsoNormal align=center style='text-align:center'>Profile Registry Leak</p>
<p class=Paragraph>This document describes a proposed solution to the registry
leak problem that we could not fix for Windows 2000.<span style="mso-spacerun:
yes"><EFBFBD> </span>Bugs 173929 and 435236 are partly caused by the registry
leak.<span style="mso-spacerun: yes"><EFBFBD> </span>Here is one example of the
problem.<span style="mso-spacerun: yes"><EFBFBD> </span>When a user logs off, userenv
tries to unload the user's profile.<span style="mso-spacerun: yes"><EFBFBD>
</span>Sometimes some process has a key open in the registry.<span
style="mso-spacerun: yes"><EFBFBD> </span>This prevents userenv from unloading the
hive.<span style="mso-spacerun: yes"><EFBFBD> </span>The spreadsheet below lists most
of the known causes of the bug.</p>
<p class=Paragraph><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
<p class=Paragraph><!--[if gte vml 1]><v:shapetype id="_x0000_t75" coordsize="21600,21600"
o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f"
stroked="f">
<v:stroke joinstyle="miter"/>
<v:formulas>
<v:f eqn="if lineDrawn pixelLineWidth 0"/>
<v:f eqn="sum @0 1 0"/>
<v:f eqn="sum 0 0 @1"/>
<v:f eqn="prod @2 1 2"/>
<v:f eqn="prod @3 21600 pixelWidth"/>
<v:f eqn="prod @3 21600 pixelHeight"/>
<v:f eqn="sum @0 0 1"/>
<v:f eqn="prod @6 1 2"/>
<v:f eqn="prod @7 21600 pixelWidth"/>
<v:f eqn="sum @8 21600 0"/>
<v:f eqn="prod @7 21600 pixelHeight"/>
<v:f eqn="sum @10 21600 0"/>
</v:formulas>
<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
<o:lock v:ext="edit" aspectratio="t"/>
</v:shapetype><v:shape id="_x0000_i1025" type="#_x0000_t75" style='width:1in;
height:56.25pt' o:ole="">
<v:imagedata src="./registry%20leak_files/image001.wmz" o:title=""/>
</v:shape><![endif]--><![if !vml]><img width=96 height=75
src="./registry%20leak_files/image002.gif" v:shapes="_x0000_i1025"><![endif]><!--[if gte mso 9]><xml>
<o:OLEObject Type="Embed" ProgID="Outlook.FileAttach" ShapeID="_x0000_i1025"
DrawAspect="Content" ObjectID="_1011110951">
</o:OLEObject>
</xml><![endif]--></p>
<p class=Paragraph>This bug has three symptoms that affect users.<span
style="mso-spacerun: yes"><EFBFBD> </span>First, if userenv cannot unload the profile
when the user logs off, userenv does not save the user's profile to the
server.<span style="mso-spacerun: yes"><EFBFBD> </span>Second, since such profiles
never get unloaded, they end up using a lot of memory on a terminal server that
has lots of users logging in.<span style="mso-spacerun: yes"><EFBFBD> </span>Third, if
the profile is still loaded the next time the user logs in, any changes stored
on the server are not loaded and are lost.</p>
<p class=Paragraph>I have a separate solution for each symptom.<span
style="mso-spacerun: yes"><EFBFBD> </span>Currently when a user logs off, if the profile
is locked we poll the profile for 60 seconds before giving up.<span
style="mso-spacerun: yes"><EFBFBD> </span>I would change the code to use RegSaveKey to
save the hive at the end of the 60 second delay rather then giving up.</p>
<p class=Paragraph>To solve the second symptom, the memory leak, I propose
using a new API that will soon be checked in.<span style="mso-spacerun: yes"><EFBFBD>
</span>With this API we can tell the registry to set an event when no one is
using the specified hive.<span style="mso-spacerun: yes"><EFBFBD> </span>At that point
we can unload the hive.<span style="mso-spacerun: yes"><EFBFBD> </span>Our code would
change so that after waiting 60 seconds for a hive to be unlocked, we would use
the new API to receive notice when the hive was finally free.<span
style="mso-spacerun: yes"><EFBFBD> </span>We would have to add a thread to wait for each
group of 64 hives (WaitForMultipleObjects can only wait for 64 events).<span
style="mso-spacerun: yes"><EFBFBD> </span>We would have to add code to tell the helper
thread which hives to wait for.<span style="mso-spacerun: yes"><EFBFBD> </span>We
would have to add code to synchronize the helper thread and LoadUserProfile in
the case where the user logs back in before the hive gets unloaded.<span
style="mso-spacerun: yes"><EFBFBD> </span>This does not completely solve the problem
because wininet never releases some of the keys that it uses.<span
style="mso-spacerun: yes"><EFBFBD> </span>However it makes sure that we behave
correctly should wininet ever get fixed.<span style="mso-spacerun: yes"><EFBFBD>
</span>We can show the terminal server team what dlls are leaking registry keys
and they can spend the time getting the dlls fixed.</p>
<p class=Code>NtUnloadKeyEx(<o:p></o:p></p>
<p class=Code><span style="mso-spacerun: yes"><EFBFBD><EFBFBD><EFBFBD> </span>IN POBJECT_ATTRIBUTES
TargetKey,<o:p></o:p></p>
<p class=Code><span style="mso-spacerun: yes"><EFBFBD><EFBFBD><EFBFBD> </span>IN HANDLE Event
OPTIONAL<o:p></o:p></p>
<p class=Code><span style="mso-spacerun: yes"><EFBFBD><EFBFBD><EFBFBD> </span>)<o:p></o:p></p>
<p class=Paragraph>It is unclear if we should solve the last symptom.<span
style="mso-spacerun: yes"><EFBFBD> </span>Currently userenv does not handle overlapped
logon sessions well.<span style="mso-spacerun: yes"><EFBFBD> </span>Userenv will lose
one set of changes.<span style="mso-spacerun: yes"><EFBFBD> </span>A solution to that
problem would probably solve this problem.<span style="mso-spacerun: yes"><EFBFBD>
</span>We could solve this problem by using another new API.<span
style="mso-spacerun: yes"><EFBFBD> </span>This API will let us rename a key even when
it is in use.<span style="mso-spacerun: yes"><EFBFBD> </span>If a user logs on and his
hive is loaded because the user has another logon session on the machine, we will
use the loaded hive and lose any changes on the server.<span
style="mso-spacerun: yes"><EFBFBD> </span>If a user logs on and his hive is loaded
because some program still has a key open from the last logon session (or some
program has loaded the hive for its own use), then we will rename the key and
load the profile from the server.<span style="mso-spacerun: yes"><EFBFBD> </span>This
requires that we change our code as described above.<span style="mso-spacerun:
yes"><EFBFBD> </span>Unfortunately, since the name ntuser.dat is already taken, we
need to use a new name for the hive from the server and remember that when the
user logs out.<span style="mso-spacerun: yes"><EFBFBD> </span>At that time we need to
make sure we copy the new hive and attempt to delete the old hive.<span
style="mso-spacerun: yes"><EFBFBD> </span>We need to handle the case where the user
has multiple hives leaked simultaneously.</p>
<p class=Code>NTSTATUS<o:p></o:p></p>
<p class=Code>NtRenameKey(<o:p></o:p></p>
<p class=Code><span style="mso-spacerun: yes"><EFBFBD><EFBFBD><EFBFBD> </span>IN HANDLE<span
style="mso-spacerun: yes"><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> </span>KeyHandle,<o:p></o:p></p>
<p class=Code><span style="mso-spacerun: yes"><EFBFBD><EFBFBD><EFBFBD> </span>IN
PUNICODE_STRING<span style="mso-spacerun: yes"><EFBFBD> </span>NewName<o:p></o:p></p>
<p class=Code><span style="mso-spacerun: yes"><EFBFBD><EFBFBD><EFBFBD> </span>)<o:p></o:p></p>
<p class=Paragraph><![if !supportEmptyParas]>&nbsp;<![endif]><o:p></o:p></p>
</div>
</body>
</html>