From: "Erich E. Hoover" <ehoover@mymail.mines.edu>
Subject: [PATCH 1/5] advapi: Implement GetNamedSecurityInfoW on top of GetSecurityInfo.
Message-Id: <CAEU2+vpBNezy2ETk-hNSUKw3rBtAi2xFwkS35nQAgQ5WBkb3Eg@mail.gmail.com>
Date: Thu, 1 Nov 2012 22:42:11 -0600

This series of patches provides a fix for Bug #31858 (Netflix Internet
Connection Problem) and Bug #31993 (Netflix hangs with loading bar at
100%).  Once this patch series has been applied then Netflix (using
Silverlight 4.x) will successfully load and play movies and TV shows,
provided that you do not move the mouse while the content is first
loading (though this only appears to be a problem when taking a
"+relay" log).  It's also worth noting that these patches supersede
91569, 91570, and 91571 and that patch 5 can be safely applied without
patches 1-4.

This particular patch implements GetNamedSecurityInfoW on top of the
more fundamental GetSecurityInfo function, permitting the return of
more accurate ownership information for files.

From f5f4baa80a3ca94102dfd3770f399ec1713c9774 Mon Sep 17 00:00:00 2001
From: Erich Hoover <ehoover@mines.edu>
Date: Thu, 1 Nov 2012 22:26:22 -0600
Subject: advapi: Implement GetNamedSecurityInfoW on top of GetSecurityInfo.

---
 dlls/advapi32/security.c |  102 +++++++---------------------------------------
 1 file changed, 14 insertions(+), 88 deletions(-)

diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c
index c86ca17..d43a2ee 100644
--- a/dlls/advapi32/security.c
+++ b/dlls/advapi32/security.c
@@ -5405,102 +5405,28 @@ DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
 {
-    DWORD needed, offset;
-    SECURITY_DESCRIPTOR_RELATIVE *relative = NULL;
-    BYTE *buffer;
+    HANDLE hfile;
+    DWORD ret;
+    DWORD access = 0;
 
     TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
            group, dacl, sacl, descriptor );
 
-    /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
-    if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
-
-    /* If no descriptor, we have to check that there's a pointer for the requested information */
-    if( !descriptor && (
-        ((info & OWNER_SECURITY_INFORMATION) && !owner)
-    ||  ((info & GROUP_SECURITY_INFORMATION) && !group)
-    ||  ((info & DACL_SECURITY_INFORMATION)  && !dacl)
-    ||  ((info & SACL_SECURITY_INFORMATION)  && !sacl)  ))
-        return ERROR_INVALID_PARAMETER;
+    if (!name) return ERROR_INVALID_PARAMETER;
 
-    needed = !descriptor ? 0 : sizeof(SECURITY_DESCRIPTOR_RELATIVE);
-    if (info & OWNER_SECURITY_INFORMATION)
-        needed += sizeof(sidWorld);
-    if (info & GROUP_SECURITY_INFORMATION)
-        needed += sizeof(sidWorld);
-    if (info & DACL_SECURITY_INFORMATION)
-        needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
+    if (info & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION))
+        access |= READ_CONTROL;
     if (info & SACL_SECURITY_INFORMATION)
-        needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
-
-    if(descriptor)
-    {
-        /* must be freed by caller */
-        *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
-        if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
-
-        if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
-        {
-            HeapFree( GetProcessHeap(), 0, *descriptor );
-            return ERROR_INVALID_SECURITY_DESCR;
-        }
-
-        relative = *descriptor;
-        relative->Control |= SE_SELF_RELATIVE;
-
-        buffer = (BYTE *)relative;
-        offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
-    }
-    else
-    {
-        buffer = HeapAlloc( GetProcessHeap(), 0, needed );
-        if (!buffer) return ERROR_NOT_ENOUGH_MEMORY;
-        offset = 0;
-    }
+        access |= ACCESS_SYSTEM_SECURITY;
 
-    if (info & OWNER_SECURITY_INFORMATION)
-    {
-        memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
-        if(relative)
-            relative->Owner = offset;
-        if (owner)
-            *owner = buffer + offset;
-        offset += sizeof(sidWorld);
-    }
-    if (info & GROUP_SECURITY_INFORMATION)
-    {
-        memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
-        if(relative)
-            relative->Group = offset;
-        if (group)
-            *group = buffer + offset;
-        offset += sizeof(sidWorld);
-    }
-    if (info & DACL_SECURITY_INFORMATION)
-    {
-        GetWorldAccessACL( (PACL)(buffer + offset) );
-        if(relative)
-        {
-            relative->Control |= SE_DACL_PRESENT;
-            relative->Dacl = offset;
-        }
-        if (dacl)
-            *dacl = (PACL)(buffer + offset);
-        offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
-    }
-    if (info & SACL_SECURITY_INFORMATION)
-    {
-        GetWorldAccessACL( (PACL)(buffer + offset) );
-        if(relative)
-        {
-            relative->Control |= SE_SACL_PRESENT;
-            relative->Sacl = offset;
-        }
-        if (sacl)
-            *sacl = (PACL)(buffer + offset);
-    }
+    hfile = CreateFileW( name, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
+    if (hfile == INVALID_HANDLE_VALUE)
+        return FALSE;
 
-    return ERROR_SUCCESS;
+    ret = GetSecurityInfo( hfile, type, info, owner, group, dacl, sacl, descriptor );
+    CloseHandle( hfile );
+    return ret;
 }
 
 /******************************************************************************
-- 
1.7.9.5