[PATCH] [Advapi32]: leaks

Eric Pouech eric.pouech at wanadoo.fr
Mon Oct 16 14:50:07 CDT 2006


- plug a couple of memory leaks (DLLs & tests)
- esp., rewrote LsaQueryInformationPublic to alloc a single
  memory chunk for a request (instead of several we were
  leaking)

A+
---

 dlls/advapi32/lsa.c            |   92 +++++++++++++++++++++++++---------------
 dlls/advapi32/registry.c       |   24 +++++++---
 dlls/advapi32/tests/security.c |    4 ++
 3 files changed, 77 insertions(+), 43 deletions(-)

diff --git a/dlls/advapi32/lsa.c b/dlls/advapi32/lsa.c
index 1d4323f..7dc025d 100644
--- a/dlls/advapi32/lsa.c
+++ b/dlls/advapi32/lsa.c
@@ -56,42 +56,58 @@ static void dumpLsaAttributes(PLSA_OBJEC
     }
 }
 
-static void ADVAPI_GetDomainName(UNICODE_STRING * name)
+static const WCHAR wVNETSUP[] = {
+    'S','y','s','t','e','m','\\',
+    'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+    'S','e','r','v','i','c','e','s','\\',
+    'V','x','D','\\','V','N','E','T','S','U','P','\0'};
+static const WCHAR wDomain[] = {'D','O','M','A','I','N','\0'};
+
+static DWORD ADVAPI_GetDomainNameSize(void)
 {
     HKEY key;
-    BOOL useDefault = TRUE;
     LONG ret;
 
-    if ((ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
-         "System\\CurrentControlSet\\Services\\VxD\\VNETSUP", 0,
-         KEY_READ, &key)) == ERROR_SUCCESS)
+    ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wVNETSUP, 0, KEY_READ, &key);
+    if (ret == ERROR_SUCCESS)
     {
         DWORD size = 0;
         static const WCHAR wg[] = { 'W','o','r','k','g','r','o','u','p',0 };
 
         ret = RegQueryValueExW(key, wg, NULL, NULL, NULL, &size);
+        RegCloseKey(key);
         if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
-        {
-            name->Buffer = HeapAlloc(GetProcessHeap(),
-                                     HEAP_ZERO_MEMORY, size);
+            return size;
+    }
+    return sizeof(wDomain);
+}
 
-            if ((ret = RegQueryValueExW(key, wg, NULL, NULL,
-                 (LPBYTE)name->Buffer, &size)) == ERROR_SUCCESS)
-            {
-                name->Length = (USHORT)(size - sizeof(WCHAR));
-                name->MaximumLength = (USHORT)size;
-                useDefault = FALSE;
-            }
-            else
-            {
-                HeapFree(GetProcessHeap(), 0, name->Buffer);
-                name->Buffer = NULL;
-            }
+static void ADVAPI_GetDomainName(UNICODE_STRING* name)
+{
+    HKEY key;
+    BOOL useDefault = TRUE;
+    LONG ret;
+
+    ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE,wVNETSUP, 0, KEY_READ, &key);
+    if (ret == ERROR_SUCCESS)
+    {
+        DWORD size = 0;
+        static const WCHAR wg[] = { 'W','o','r','k','g','r','o','u','p',0 };
+
+        size = name->MaximumLength;
+        if ((ret = RegQueryValueExW(key, wg, NULL, NULL,
+                                    (LPBYTE)name->Buffer, &size)) == ERROR_SUCCESS)
+        {
+            name->Length = (USHORT)(size - sizeof(WCHAR));
+            useDefault = FALSE;
         }
         RegCloseKey(key);
     }
     if (useDefault)
-        RtlCreateUnicodeStringFromAsciiz(name, "DOMAIN");
+    {
+        name->Length = (USHORT)(sizeof(wDomain) - sizeof(WCHAR));
+        memcpy(name->Buffer, wDomain, name->Length);
+    }
 }
 
 /******************************************************************************
@@ -431,9 +447,14 @@ NTSTATUS WINAPI LsaQueryInformationPolic
             /* Only the domain name is valid for the local computer.
              * All other fields are zero.
              */
-            PPOLICY_PRIMARY_DOMAIN_INFO pinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                                          sizeof(POLICY_PRIMARY_DOMAIN_INFO));
+            PPOLICY_PRIMARY_DOMAIN_INFO pinfo;
+            DWORD size = ADVAPI_GetDomainNameSize();
 
+            pinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                              sizeof(POLICY_PRIMARY_DOMAIN_INFO) + size);
+
+            pinfo->Name.Buffer = (WCHAR*)(pinfo + 1);
+            pinfo->Name.MaximumLength = size;
             ADVAPI_GetDomainName(&pinfo->Name);
 
             TRACE("setting domain to %s\n", debugstr_w(pinfo->Name.Buffer));
@@ -448,28 +469,24 @@ NTSTATUS WINAPI LsaQueryInformationPolic
                 POLICY_ACCOUNT_DOMAIN_INFO info;
                 SID sid;
                 DWORD padding[3];
+                WCHAR domain[MAX_COMPUTERNAME_LENGTH + 1];
             };
 
-            struct di * xdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*xdi));
             DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
-            LPWSTR buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize * sizeof(WCHAR));
+            struct di * xdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*xdi));
 
             xdi->info.DomainName.MaximumLength = dwSize * sizeof(WCHAR);
-
-            if (GetComputerNameW(buf, &dwSize))
-            {
-                xdi->info.DomainName.Buffer = buf;
+            xdi->info.DomainName.Buffer = xdi->domain;
+            if (GetComputerNameW(xdi->info.DomainName.Buffer, &dwSize))
                 xdi->info.DomainName.Length = dwSize * sizeof(WCHAR);
-            }
 
             TRACE("setting name to %s\n", debugstr_w(xdi->info.DomainName.Buffer));
 
-            xdi->info.DomainSid = &(xdi->sid);
+            xdi->info.DomainSid = &xdi->sid;
 
             /* read the computer SID from the registry */
-            if (!ADVAPI_GetComputerSid(&(xdi->sid)))
+            if (!ADVAPI_GetComputerSid(&xdi->sid))
             {
-                HeapFree(GetProcessHeap(), 0, buf);
                 HeapFree(GetProcessHeap(), 0, xdi);
 
                 WARN("Computer SID not found\n");
@@ -487,9 +504,14 @@ NTSTATUS WINAPI LsaQueryInformationPolic
             /* Only the domain name is valid for the local computer.
              * All other fields are zero.
              */
-            PPOLICY_DNS_DOMAIN_INFO pinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-                                                      sizeof(POLICY_DNS_DOMAIN_INFO));
+            PPOLICY_DNS_DOMAIN_INFO pinfo;
+            DWORD size = ADVAPI_GetDomainNameSize();
+
+            pinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                              sizeof(POLICY_DNS_DOMAIN_INFO) + size);
 
+            pinfo->Name.Buffer = (WCHAR*)(pinfo + 1);
+            pinfo->Name.MaximumLength = size;
             ADVAPI_GetDomainName(&pinfo->Name);
 
             TRACE("setting domain to %s\n", debugstr_w(pinfo->Name.Buffer));
diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index 26c5ae9..fafa03c 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -1887,6 +1887,7 @@ LONG WINAPI RegLoadKeyW( HKEY hkey, LPCW
 {
     OBJECT_ATTRIBUTES destkey, file;
     UNICODE_STRING subkeyW, filenameW;
+    NTSTATUS status;
 
     if (!(hkey = get_special_root_hkey(hkey))) return ERROR_INVALID_HANDLE;
 
@@ -1906,7 +1907,9 @@ LONG WINAPI RegLoadKeyW( HKEY hkey, LPCW
     file.SecurityQualityOfService = NULL;
     RtlDosPathNameToNtPathName_U(filename, &filenameW, NULL, NULL);
 
-    return RtlNtStatusToDosError( NtLoadKey(&destkey, &file) );
+    status = NtLoadKey(&destkey, &file);
+    RtlFreeUnicodeString(&filenameW);
+    return RtlNtStatusToDosError( status );
 }
 
 
@@ -1920,17 +1923,22 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCS
     UNICODE_STRING subkeyW, filenameW;
     STRING subkeyA, filenameA;
     NTSTATUS status;
+    LONG ret;
 
     RtlInitAnsiString(&subkeyA, subkey);
     RtlInitAnsiString(&filenameA, filename);
 
-    if ((status = RtlAnsiStringToUnicodeString(&subkeyW, &subkeyA, TRUE)))
-        return RtlNtStatusToDosError(status);
-
-    if ((status = RtlAnsiStringToUnicodeString(&filenameW, &filenameA, TRUE)))
-        return RtlNtStatusToDosError(status);
-
-    return RegLoadKeyW(hkey, subkeyW.Buffer, filenameW.Buffer);
+    RtlInitUnicodeString(&subkeyW, NULL);
+    RtlInitUnicodeString(&filenameW, NULL);
+    if (!(status = RtlAnsiStringToUnicodeString(&subkeyW, &subkeyA, TRUE)) &&
+        !(status = RtlAnsiStringToUnicodeString(&filenameW, &filenameA, TRUE)))
+    {
+        ret = RegLoadKeyW(hkey, subkeyW.Buffer, filenameW.Buffer);
+    }
+    else ret = RtlNtStatusToDosError(status);
+    RtlFreeUnicodeString(&subkeyW);
+    RtlFreeUnicodeString(&filenameW);
+    return ret;
 }
 
 
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index e0891ad..54112d2 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -100,6 +100,7 @@ static void test_str_sid(const char *str
             trace(" %s: %s\n", str_sid, temp);
             LocalFree(temp);
         }
+        LocalFree(psid);
     }
     else
     {
@@ -833,6 +834,7 @@ static void test_token_attr(void)
     pConvertSidToStringSidA(User->User.Sid, &SidString);
     trace("TokenUser: %s attr: 0x%08x\n", SidString, User->User.Attributes);
     LocalFree(SidString);
+    HeapFree(GetProcessHeap(), 0, User);
 
     /* privileges */
     ret = GetTokenInformation(Token, TokenPrivileges, NULL, 0, &Size);
@@ -1044,6 +1046,8 @@ static void test_LookupAccountSid(void)
        "LookupAccountSidW() Expected dom_size = %u, got %u\n",
        real_dom_sizeW + 1, dom_sizeW);
 
+    FreeSid(pUsersSid);
+
     pCreateWellKnownSid = (fnCreateWellKnownSid)GetProcAddress( hmod, "CreateWellKnownSid" );
 
     if (pCreateWellKnownSid && pConvertSidToStringSidA)



More information about the wine-patches mailing list