Synchronize up to trunk's revision r57689.
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 7 Nov 2012 23:07:18 +0000 (23:07 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 7 Nov 2012 23:07:18 +0000 (23:07 +0000)
svn path=/branches/ros-csrss/; revision=57690

37 files changed:
Doxyfile
base/shell/explorer/desktop/desktop.cpp
base/shell/explorer/desktop/desktop.h
base/shell/explorer/shell/shellbrowser.cpp
base/shell/explorer/shell/shellbrowser.h
base/shell/explorer/utility/window.cpp
base/shell/explorer/utility/window.h
boot/bootdata/hivesys_amd64.inf
boot/bootdata/hivesys_i386.inf
dll/ntdll/rtl/version.c
dll/win32/advapi32/advapi32.h
dll/win32/advapi32/sec/sid.c
dll/win32/kernel32/client/version.c
dll/win32/netapi32/CMakeLists.txt
dll/win32/netapi32/local_group.c
dll/win32/netapi32/netapi32.c
dll/win32/netapi32/netapi32.h [new file with mode: 0644]
dll/win32/netapi32/netapi32.spec
dll/win32/samsrv/samrpc.c
lib/rtl/version.c
ntoskrnl/mm/ARM3/procsup.c
ntoskrnl/rtl/misc.c
win32ss/CMakeLists.txt
win32ss/gdi/gdi32/CMakeLists.txt
win32ss/include/ntuser.h
win32ss/include/ntusrtyp.h
win32ss/user/ntuser/class.c
win32ss/user/ntuser/class.h
win32ss/user/ntuser/cursoricon.c
win32ss/user/ntuser/cursoricon.h
win32ss/user/ntuser/cursoricon_new.c
win32ss/user/ntuser/simplecall.c
win32ss/user/user32/CMakeLists.txt
win32ss/user/user32/controls/edit.c
win32ss/user/user32/windows/cursoricon_new.c
win32ss/user/user32/windows/dialog.c
win32ss/user/user32/windows/mdi.c

index 386ca57..75a2bcb 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -196,7 +196,7 @@ ALIASES                =
 # For instance, some of the names that are used will be different. The list 
 # of all members will be omitted, etc.
 
-OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_FOR_C  = NO
 
 # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
 # sources only. Doxygen will then generate output that is more tailored for 
@@ -236,7 +236,7 @@ EXTENSION_MAPPING      =
 # func(std::string) {}). This also make the inheritance and collaboration 
 # diagrams that involve STL classes more complete and accurate.
 
-BUILTIN_STL_SUPPORT    = NO
+BUILTIN_STL_SUPPORT    = YES
 
 # If you use Microsoft's C++/CLI language, you should set this option to YES to 
 # enable parsing support.
index ed61357..c00308f 100644 (file)
@@ -479,6 +479,26 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
         SendMessage(g_Globals._hwndShellView, nmsg, wparam, lparam);
         break;
 
+      case PM_TRANSLATE_MSG:
+      {
+            /* TranslateAccelerator is called for all explorer windows that are open 
+               so we have to decide if this is the correct recipient */
+            LPMSG lpmsg = (LPMSG)lparam;
+            HWND hwnd = lpmsg->hwnd;
+
+            while(hwnd)
+            {
+                if(hwnd == _hwnd)
+                    break;
+
+                hwnd = GetParent(hwnd);
+            }
+
+            if (hwnd)
+                return _pShellView->TranslateAccelerator(lpmsg) == S_OK;
+            return false;
+      }
+
          default: def:
                return super::WndProc(nmsg, wparam, lparam);
        }
index ab46611..2fffb4c 100644 (file)
@@ -48,9 +48,9 @@ protected:
 
 
  /// Implementation of the Explorer desktop window
-struct DesktopWindow : public Window, public IShellBrowserImpl
+struct DesktopWindow : public PreTranslateWindow, public IShellBrowserImpl
 {
-       typedef Window super;
+       typedef PreTranslateWindow super;
 
        DesktopWindow(HWND hwnd);
        ~DesktopWindow();
index 44ba375..1c74c86 100644 (file)
@@ -599,6 +599,27 @@ bool ShellBrowser::jump_to_pidl(LPCITEMIDLIST pidl)
        return false;
 }
 
+bool ShellBrowser::TranslateAccelerator(LPMSG lpmsg)
+{
+    HWND hwnd;
+
+    /* TranslateAccelerator is called for all explorer windows that are open 
+       so we have to decide if this is the correct recipient */
+    hwnd = lpmsg->hwnd;
+
+    while(hwnd)
+    {
+        if(hwnd == _hwnd)
+            break;
+
+        hwnd = GetParent(hwnd);
+    }
+
+    if (hwnd)
+        return _pShellView->TranslateAccelerator(lpmsg) == S_OK;
+
+    return false;
+}
 
 bool ShellBrowser::select_folder(Entry* entry, bool expand)
 {
@@ -707,6 +728,9 @@ LRESULT MDIShellBrowserChild::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
                SendMessage(_right_hwnd, WM_SYSCOLORCHANGE, 0, 0);
                break;
 
+         case PM_TRANSLATE_MSG:
+               return _shellBrowser->TranslateAccelerator((MSG*)lparam);
+
          default:
                return super::WndProc(nmsg, wparam, lparam);
        }
index 886d5ce..be910f1 100644 (file)
@@ -141,6 +141,8 @@ struct ShellBrowser : public IShellBrowserImpl
 
        void    invalidate_cache();
 
+       bool TranslateAccelerator(LPMSG lpmsg);
+
 protected:
        HWND                    _hwnd;
        HWND                    _hwndFrame;
index 4ad750f..bb0814d 100644 (file)
@@ -591,6 +591,14 @@ void Window::unregister_pretranslate(HWND hwnd)
 
 BOOL Window::pretranslate_msg(LPMSG pmsg)
 {
+    if ((pmsg->message != WM_KEYDOWN) &&
+        (pmsg->message != WM_SYSKEYDOWN) &&
+        (pmsg->message != WM_SYSCHAR) &&
+        (pmsg->message != WM_CHAR))
+    {
+        return FALSE;
+    }
+
        for(WindowSet::const_iterator it=Window::s_pretranslate_windows.begin(); it!=s_pretranslate_windows.end(); ++it)
                if (SendMessage(*it, PM_TRANSLATE_MSG, 0, (LPARAM)pmsg))
                        return TRUE;
index 3f556b9..3bf913a 100644 (file)
@@ -282,13 +282,28 @@ struct MenuInfo
 #define        Frame_GetMenuInfo(hwnd) ((MenuInfo*)SNDMSG(hwnd, PM_FRM_GET_MENUINFO, 0, 0))
 
 
+ /**
+       PreTranslateWindow is used to register windows to be called by Window::pretranslate_msg().
+       This way you get PM_TRANSLATE_MSG messages before the message loop dispatches messages.
+       You can then for example use TranslateAccelerator() to implement key shortcuts.
+ */
+struct PreTranslateWindow : public Window
+{
+       typedef Window super;
+
+       PreTranslateWindow(HWND);
+       ~PreTranslateWindow();
+};
+
+
+
  /**
        Class ChildWindow represents MDI child windows.
        It is used with class MainFrame.
  */
-struct ChildWindow : public Window
+struct ChildWindow : public PreTranslateWindow
 {
-       typedef Window super;
+       typedef PreTranslateWindow super;
 
        ChildWindow(HWND hwnd, const ChildWndInfo& info);
 
@@ -325,20 +340,6 @@ protected:
 #define        PM_SETSTATUSTEXT                (WM_APP+0x1E)
 
 
- /**
-       PreTranslateWindow is used to register windows to be called by Window::pretranslate_msg().
-       This way you get PM_TRANSLATE_MSG messages before the message loop dispatches messages.
-       You can then for example use TranslateAccelerator() to implement key shortcuts.
- */
-struct PreTranslateWindow : public Window
-{
-       typedef Window super;
-
-       PreTranslateWindow(HWND);
-       ~PreTranslateWindow();
-};
-
-
  /**
        The class DialogWindow implements modeless dialogs, which are managed by
        Window::dispatch_dialog_msg() in Window::MessageLoop().
index ad480cb..a6585af 100644 (file)
@@ -1130,8 +1130,11 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Print\Monitors",,0x00000012
 HKLM,"SYSTEM\CurrentControlSet\Control\Print\Monitors\Local Port","Driver",2,"localspl.dll"
 HKLM,"SYSTEM\CurrentControlSet\Control\Print\Printers",,0x00000012
 
-HKLM,"SYSTEM\CurrentControlSet\Control\ProductOptions","ProductType",2,"WinNT"
-HKLM,"SYSTEM\CurrentControlSet\Control\ProductOptions","ProductSuite",0x00010002,""
+HKLM,"SYSTEM\CurrentControlSet\Control\ProductOptions","ProductType",2,"ServerNT"
+HKLM,"SYSTEM\CurrentControlSet\Control\ProductOptions","ProductSuite",0x00010002,"Terminal Server"
+; ReactOS specific - by default we report ourselves as Server for the user,
+; but we can also report as Workstation if some application needs it.
+HKLM,"SYSTEM\CurrentControlSet\Control\ReactOS\Settings\Version","ReportAsWorkstation",0x00010001,0x00000000
 ; Some installers check for SP1
 HKLM,"SYSTEM\CurrentControlSet\Control\Windows","CSDVersion",0x00010001,0x00000100
 
index ad480cb..a6585af 100644 (file)
@@ -1130,8 +1130,11 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Print\Monitors",,0x00000012
 HKLM,"SYSTEM\CurrentControlSet\Control\Print\Monitors\Local Port","Driver",2,"localspl.dll"
 HKLM,"SYSTEM\CurrentControlSet\Control\Print\Printers",,0x00000012
 
-HKLM,"SYSTEM\CurrentControlSet\Control\ProductOptions","ProductType",2,"WinNT"
-HKLM,"SYSTEM\CurrentControlSet\Control\ProductOptions","ProductSuite",0x00010002,""
+HKLM,"SYSTEM\CurrentControlSet\Control\ProductOptions","ProductType",2,"ServerNT"
+HKLM,"SYSTEM\CurrentControlSet\Control\ProductOptions","ProductSuite",0x00010002,"Terminal Server"
+; ReactOS specific - by default we report ourselves as Server for the user,
+; but we can also report as Workstation if some application needs it.
+HKLM,"SYSTEM\CurrentControlSet\Control\ReactOS\Settings\Version","ReportAsWorkstation",0x00010001,0x00000000
 ; Some installers check for SP1
 HKLM,"SYSTEM\CurrentControlSet\Control\Windows","CSDVersion",0x00010001,0x00000100
 
index ce832c3..66193fe 100644 (file)
@@ -8,13 +8,64 @@
  *                  Created 01/11/98
  */
 
-/* INCLUDES ****************************************************************/
+/* INCLUDES *******************************************************************/
 
 #include <ntdll.h>
 #define NDEBUG
 #include <debug.h>
 
-/* FUNCTIONS ****************************************************************/
+/* FUNCTIONS ******************************************************************/
+
+/* HACK: ReactOS specific changes, see bug-reports CORE-6611 and CORE-4620 (aka. #5003) */
+static VOID NTAPI
+SetRosSpecificInfo(IN OUT PRTL_OSVERSIONINFOEXW VersionInformation)
+{
+    CHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
+    PKEY_VALUE_PARTIAL_INFORMATION kvpInfo = (PVOID)Buffer;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    ULONG ReportAsWorkstation = 0;
+    HANDLE hKey;
+    ULONG Length;
+    NTSTATUS Status;
+    UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version");
+    UNICODE_STRING ValName = RTL_CONSTANT_STRING(L"ReportAsWorkstation");
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &KeyName,
+                               OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    /* Don't change anything if the key doesn't exist */
+    Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
+    if (NT_SUCCESS(Status))
+    {
+        /* Get the value from the registry and make sure it's a 32-bit value */
+        Status = NtQueryValueKey(hKey,
+                                 &ValName,
+                                 KeyValuePartialInformation,
+                                 kvpInfo,
+                                 sizeof(Buffer),
+                                 &Length);
+        if (NT_SUCCESS(Status) &&
+            (kvpInfo->Type == REG_DWORD) &&
+            (kvpInfo->DataLength == sizeof(ULONG)))
+        {
+            /* Is the value set? */
+            ReportAsWorkstation = *(PULONG)kvpInfo->Data;
+            if ((VersionInformation->wProductType == VER_NT_SERVER) &&
+                (ReportAsWorkstation != 0))
+            {
+                /* It is, modify the product type to report a workstation */
+                VersionInformation->wProductType = VER_NT_WORKSTATION;
+                DPRINT1("We modified the reported OS from NtProductServer to NtProductWinNt\n");
+            }
+        }
+
+        /* Close the handle */
+        NtClose(hKey);
+    }
+}
 
 /**********************************************************************
  * NAME                                                        EXPORTED
  *
  * @implemented
  */
-
 BOOLEAN NTAPI
 RtlGetNtProductType(PNT_PRODUCT_TYPE ProductType)
 {
-  *ProductType = SharedUserData->NtProductType;
-  return(TRUE);
+    *ProductType = SharedUserData->NtProductType;
+    return TRUE;
 }
 
 /**********************************************************************
@@ -71,7 +121,6 @@ RtlGetNtProductType(PNT_PRODUCT_TYPE ProductType)
  *
  * @implemented
  */
-
 VOID NTAPI
 RtlGetNtVersionNumbers(OUT LPDWORD pdwMajorVersion,
                        OUT LPDWORD pdwMinorVersion,
@@ -101,49 +150,56 @@ RtlGetNtVersionNumbers(OUT LPDWORD pdwMajorVersion,
 }
 
 /*
-* @implemented
-*/
+ * @implemented
+ * @note User-mode version of RtlGetVersion in ntoskrnl/rtl/misc.c
+ */
 NTSTATUS NTAPI
-RtlGetVersion(RTL_OSVERSIONINFOW *Info)
+RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
 {
-   LONG i, MaxLength;
-
-   if (Info->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOW) ||
-       Info->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
-   {
-      PPEB Peb = NtCurrentPeb();
-
-      Info->dwMajorVersion = Peb->OSMajorVersion;
-      Info->dwMinorVersion = Peb->OSMinorVersion;
-      Info->dwBuildNumber = Peb->OSBuildNumber;
-      Info->dwPlatformId = Peb->OSPlatformId;
-      RtlZeroMemory(Info->szCSDVersion, sizeof(Info->szCSDVersion));
-      if(((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
-      {
-        MaxLength = (sizeof(Info->szCSDVersion) / sizeof(Info->szCSDVersion[0])) - 1;
-        i = _snwprintf(Info->szCSDVersion,
-                       MaxLength,
-                       L"Service Pack %d",
-                       ((Peb->OSCSDVersion >> 8) & 0xFF));
-        if (i < 0)
+    LONG i, MaxLength;
+
+    if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOW) ||
+        lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
+    {
+        PPEB Peb = NtCurrentPeb();
+
+        lpVersionInformation->dwMajorVersion = Peb->OSMajorVersion;
+        lpVersionInformation->dwMinorVersion = Peb->OSMinorVersion;
+        lpVersionInformation->dwBuildNumber = Peb->OSBuildNumber;
+        lpVersionInformation->dwPlatformId = Peb->OSPlatformId;
+        RtlZeroMemory(lpVersionInformation->szCSDVersion, sizeof(lpVersionInformation->szCSDVersion));
+
+        if(((Peb->OSCSDVersion >> 8) & 0xFF) != 0)
         {
-           /* null-terminate if it was overflowed */
-           Info->szCSDVersion[MaxLength] = L'\0';
+            MaxLength = (sizeof(lpVersionInformation->szCSDVersion) / sizeof(lpVersionInformation->szCSDVersion[0])) - 1;
+            i = _snwprintf(lpVersionInformation->szCSDVersion,
+                           MaxLength,
+                           L"Service Pack %d",
+                           ((Peb->OSCSDVersion >> 8) & 0xFF));
+            if (i < 0)
+            {
+                /* Null-terminate if it was overflowed */
+                lpVersionInformation->szCSDVersion[MaxLength] = L'\0';
+            }
         }
-      }
-      if (Info->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
-      {
-         RTL_OSVERSIONINFOEXW *InfoEx = (RTL_OSVERSIONINFOEXW *)Info;
-         InfoEx->wServicePackMajor = (Peb->OSCSDVersion >> 8) & 0xFF;
-         InfoEx->wServicePackMinor = Peb->OSCSDVersion & 0xFF;
-         InfoEx->wSuiteMask = SharedUserData->SuiteMask & 0xFFFF;
-         InfoEx->wProductType = SharedUserData->NtProductType;
-      }
-
-      return STATUS_SUCCESS;
-   }
-
-   return STATUS_INVALID_PARAMETER;
+
+        if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
+        {
+            PRTL_OSVERSIONINFOEXW InfoEx = (PRTL_OSVERSIONINFOEXW)lpVersionInformation;
+            InfoEx->wServicePackMajor = (Peb->OSCSDVersion >> 8) & 0xFF;
+            InfoEx->wServicePackMinor = Peb->OSCSDVersion & 0xFF;
+            InfoEx->wSuiteMask = SharedUserData->SuiteMask & 0xFFFF;
+            InfoEx->wProductType = SharedUserData->NtProductType;
+            InfoEx->wReserved = 0;
+
+            /* HACK: ReactOS specific changes, see bug-reports CORE-6611 and CORE-4620 (aka. #5003) */
+            SetRosSpecificInfo(InfoEx);
+        }
+
+        return STATUS_SUCCESS;
+    }
+
+    return STATUS_INVALID_PARAMETER;
 }
 
 /* EOF */
index 3c7d2a9..22c87c4 100644 (file)
 #define FN_PROGRESSA FN_PROGRESS
 #endif
 
-/* sid.c */
-
-BOOL ADVAPI_GetComputerSid(PSID sid);
-
 /* rpc.c */
 
 RPC_STATUS EvtBindRpc(LPCWSTR pszMachine,
index 91b5db6..c289010 100644 (file)
@@ -18,17 +18,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
 BOOL WINAPI
 AddAuditAccessAceEx(PACL pAcl,
-                   DWORD dwAceRevision,
-                   DWORD AceFlags,
-                   DWORD dwAccessMask,
-                   PSID pSid,
-                   BOOL bAuditSuccess,
-                   BOOL bAuditFailure);
+                    DWORD dwAceRevision,
+                    DWORD AceFlags,
+                    DWORD dwAccessMask,
+                    PSID pSid,
+                    BOOL bAuditSuccess,
+                    BOOL bAuditFailure);
 
 typedef struct RECORD
 {
-       LPCWSTR key;
-       DWORD value;
+    LPCWSTR key;
+    DWORD value;
 } RECORD;
 
 
@@ -299,67 +299,6 @@ static __inline BOOL set_ntstatus( NTSTATUS status )
     return !status;
 }
 
-/************************************************************
- *                ADVAPI_GetComputerSid
- *
- * Reads the computer SID from the registry.
- */
-BOOL ADVAPI_GetComputerSid(PSID sid)
-{
-    HKEY key;
-    LONG ret;
-    BOOL retval = FALSE;
-    static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
-    static const WCHAR V[] = { 'V',0 };
-
-    if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
-        KEY_READ, &key)) == ERROR_SUCCESS)
-    {
-        DWORD size = 0;
-        ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
-        if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
-        {
-            BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
-            if (data)
-            {
-                if ((ret = RegQueryValueExW(key, V, NULL, NULL,
-                     data, &size)) == ERROR_SUCCESS)
-                {
-                    /* the SID is in the last 24 bytes of the binary data */
-                    CopyMemory(sid, &data[size-24], 24);
-                    retval = TRUE;
-                }
-                HeapFree(GetProcessHeap(), 0, data);
-            }
-        }
-        RegCloseKey(key);
-    }
-
-    if(retval == TRUE) return retval;
-
-    /* create a new random SID */
-    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
-        0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
-    {
-        PSID new_sid;
-        SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
-        DWORD id[3];
-
-        if (RtlGenRandom(id, sizeof(id)))
-        {
-            if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
-            {
-                if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
-                    retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
-
-                FreeSid(new_sid);
-            }
-        }
-        RegCloseKey(key);
-    }
-
-    return retval;
-}
 
 /* Exported functions */
 
@@ -794,6 +733,7 @@ ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR Securi
 {
     LPWSTR wstr;
     ULONG len;
+
     if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
     {
         int lenA;
@@ -971,15 +911,15 @@ static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
     while (*szAcl != '(')
     {
         if (*szAcl == 'P')
-       {
+        {
             flags |= SE_DACL_PROTECTED;
-       }
+        }
         else if (*szAcl == 'A')
         {
             szAcl++;
             if (*szAcl == 'R')
                 flags |= SE_DACL_AUTO_INHERIT_REQ;
-           else if (*szAcl == 'I')
+            else if (*szAcl == 'I')
                 flags |= SE_DACL_AUTO_INHERITED;
         }
         szAcl++;
@@ -1059,7 +999,7 @@ static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
         if (!lpaf->wstr)
             return 0;
 
-       flags |= lpaf->value;
+        flags |= lpaf->value;
         szAcl += len;
     }
 
@@ -1081,15 +1021,15 @@ static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
     {
         LPCWSTR p = szAcl;
 
-       while (*p && *p != ';')
+        while (*p && *p != ';')
             p++;
 
-       if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
-       {
-           rights = strtoulW(szAcl, NULL, 16);
-           szAcl = p;
-       }
-       else
+        if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
+        {
+            rights = strtoulW(szAcl, NULL, 16);
+            szAcl = p;
+        }
+        else
             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
     }
     else
@@ -1099,16 +1039,16 @@ static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
             const ACEFLAG *lpaf = AceRights;
 
             while (lpaf->wstr &&
-               (len = strlenW(lpaf->wstr)) &&
-               strncmpW(lpaf->wstr, szAcl, len))
-           {
-               lpaf++;
-           }
+                   (len = strlenW(lpaf->wstr)) &&
+                   strncmpW(lpaf->wstr, szAcl, len))
+            {
+                lpaf++;
+            }
 
             if (!lpaf->wstr)
                 return 0;
 
-           rights |= lpaf->value;
+            rights |= lpaf->value;
             szAcl += len;
         }
     }
@@ -1123,8 +1063,11 @@ static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
  * 
  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
  */
-static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
-    PACL pAcl, LPDWORD cBytes)
+static BOOL
+ParseStringAclToAcl(LPCWSTR StringAcl,
+                    LPDWORD lpdwFlags, 
+                    PACL pAcl,
+                    LPDWORD cBytes)
 {
     DWORD val;
     DWORD sidlen;
@@ -1136,7 +1079,7 @@ static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
     TRACE("%s\n", debugstr_w(StringAcl));
 
     if (!StringAcl)
-       return FALSE;
+        return FALSE;
 
     if (pAcl) /* pAce is only useful if we're setting values */
         pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
@@ -1151,23 +1094,23 @@ static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
 
         /* Parse ACE type */
         val = ParseAceStringType(&StringAcl);
-       if (pAce)
+        if (pAce)
             pAce->Header.AceType = (BYTE) val;
         if (*StringAcl != ';')
             goto lerr;
         StringAcl++;
 
         /* Parse ACE flags */
-       val = ParseAceStringFlags(&StringAcl);
-       if (pAce)
+        val = ParseAceStringFlags(&StringAcl);
+        if (pAce)
             pAce->Header.AceFlags = (BYTE) val;
         if (*StringAcl != ';')
             goto lerr;
         StringAcl++;
 
         /* Parse ACE rights */
-       val = ParseAceStringRights(&StringAcl);
-       if (pAce)
+        val = ParseAceStringRights(&StringAcl);
+        if (pAce)
             pAce->Mask = val;
         if (*StringAcl != ';')
             goto lerr;
@@ -1191,10 +1134,10 @@ static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
 
         /* Parse ACE account sid */
         if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
-       {
+        {
             while (*StringAcl && *StringAcl != ')')
                 StringAcl++;
-       }
+        }
 
         if (*StringAcl != ')')
             goto lerr;
@@ -1238,10 +1181,10 @@ lerr:
 /******************************************************************************
  * ParseStringSecurityDescriptorToSecurityDescriptor
  */
-static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
-    LPCWSTR StringSecurityDescriptor,
-    SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
-    LPDWORD cBytes)
+static BOOL
+ParseStringSecurityDescriptorToSecurityDescriptor(LPCWSTR StringSecurityDescriptor,
+                                                  SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
+                                                  LPDWORD cBytes)
 {
     BOOL bret = FALSE;
     WCHAR toktype;
@@ -1259,21 +1202,21 @@ static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
     {
         toktype = *StringSecurityDescriptor;
 
-       /* Expect char identifier followed by ':' */
-       StringSecurityDescriptor++;
+        /* Expect char identifier followed by ':' */
+        StringSecurityDescriptor++;
         if (*StringSecurityDescriptor != ':')
         {
             SetLastError(ERROR_INVALID_PARAMETER);
             goto lend;
         }
-       StringSecurityDescriptor++;
+        StringSecurityDescriptor++;
 
-       /* Extract token */
-       lptoken = StringSecurityDescriptor;
-       while (*lptoken && *lptoken != ':')
+        /* Extract token */
+        lptoken = StringSecurityDescriptor;
+        while (*lptoken && *lptoken != ':')
             lptoken++;
 
-       if (*lptoken)
+        if (*lptoken)
             lptoken--;
 
         len = lptoken - StringSecurityDescriptor;
@@ -1281,7 +1224,7 @@ static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
         tok[len] = 0;
 
         switch (toktype)
-       {
+        {
             case 'O':
             {
                 DWORD bytes;
@@ -1295,7 +1238,7 @@ static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
                     lpNext += bytes; /* Advance to next token */
                 }
 
-               *cBytes += bytes;
+                *cBytes += bytes;
 
                 break;
             }
@@ -1313,13 +1256,13 @@ static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
                     lpNext += bytes; /* Advance to next token */
                 }
 
-               *cBytes += bytes;
+                *cBytes += bytes;
 
                 break;
             }
 
             case 'D':
-           {
+            {
                 DWORD flags;
                 DWORD bytes;
 
@@ -1331,11 +1274,11 @@ static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
                     SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
                     lpNext += bytes; /* Advance to next token */
-               }
+                }
 
-               *cBytes += bytes;
+                *cBytes += bytes;
 
-               break;
+                break;
             }
 
             case 'S':
@@ -1351,18 +1294,18 @@ static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
                     SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
                     lpNext += bytes; /* Advance to next token */
-               }
+                }
 
-               *cBytes += bytes;
+                *cBytes += bytes;
 
-               break;
+                break;
             }
 
             default:
                 FIXME("Unknown token\n");
                 SetLastError(ERROR_INVALID_PARAMETER);
-               goto lend;
-       }
+                goto lend;
+        }
 
         StringSecurityDescriptor = lptoken;
     }
@@ -1378,11 +1321,11 @@ lend:
  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
  * @implemented
  */
-BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
-        LPCWSTR StringSecurityDescriptor,
-        DWORD StringSDRevision,
-        PSECURITY_DESCRIPTOR* SecurityDescriptor,
-        PULONG SecurityDescriptorSize)
+BOOL WINAPI
+ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor,
+                                                     DWORD StringSDRevision,
+                                                     PSECURITY_DESCRIPTOR* SecurityDescriptor,
+                                                     PULONG SecurityDescriptorSize)
 {
     DWORD cBytes;
     SECURITY_DESCRIPTOR* psd;
@@ -1403,13 +1346,13 @@ BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
     else if (StringSDRevision != SID_REVISION)
     {
         SetLastError(ERROR_UNKNOWN_REVISION);
-       goto lend;
+        goto lend;
     }
 
     /* Compute security descriptor length */
     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
         NULL, &cBytes))
-       goto lend;
+        goto lend;
 
     psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
     if (!psd) goto lend;
@@ -1421,14 +1364,14 @@ BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
              (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
     {
         LocalFree(psd);
-       goto lend;
+        goto lend;
     }
 
     if (SecurityDescriptorSize)
         *SecurityDescriptorSize = cBytes;
 
     bret = TRUE;
+
 lend:
     TRACE(" ret=%d\n", bret);
     return bret;
@@ -1440,11 +1383,12 @@ lend:
  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
  * @implemented
  */
-BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
-        LPCSTR StringSecurityDescriptor,
-        DWORD StringSDRevision,
-        PSECURITY_DESCRIPTOR* SecurityDescriptor,
-        PULONG SecurityDescriptorSize)
+BOOL
+WINAPI
+ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor,
+                                                     DWORD StringSDRevision,
+                                                     PSECURITY_DESCRIPTOR* SecurityDescriptor,
+                                                     PULONG SecurityDescriptorSize)
 {
     UINT len;
     BOOL ret = FALSE;
@@ -1469,7 +1413,8 @@ BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 EqualPrefixSid(PSID pSid1,
                PSID pSid2)
 {
@@ -1480,7 +1425,8 @@ EqualPrefixSid(PSID pSid1,
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 EqualSid(PSID pSid1,
          PSID pSid2)
 {
@@ -1495,7 +1441,8 @@ EqualSid(PSID pSid1,
  *  Docs says this function does NOT return a value
  *  even thou it's defined to return a PVOID...
  */
-PVOID WINAPI
+PVOID
+WINAPI
 FreeSid(PSID pSid)
 {
     return RtlFreeSid(pSid);
@@ -1505,7 +1452,8 @@ FreeSid(PSID pSid)
 /*
  * @implemented
  */
-DWORD WINAPI
+DWORD
+WINAPI
 GetLengthSid(PSID pSid)
 {
     return (DWORD)RtlLengthSid(pSid);
@@ -1515,7 +1463,8 @@ GetLengthSid(PSID pSid)
 /*
  * @implemented
  */
-PSID_IDENTIFIER_AUTHORITY WINAPI
+PSID_IDENTIFIER_AUTHORITY
+WINAPI
 GetSidIdentifierAuthority(PSID pSid)
 {
     return RtlIdentifierAuthoritySid(pSid);
@@ -1525,7 +1474,8 @@ GetSidIdentifierAuthority(PSID pSid)
 /*
  * @implemented
  */
-DWORD WINAPI
+DWORD
+WINAPI
 GetSidLengthRequired(UCHAR nSubAuthorityCount)
 {
     return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount);
@@ -1535,7 +1485,8 @@ GetSidLengthRequired(UCHAR nSubAuthorityCount)
 /*
  * @implemented
  */
-PDWORD WINAPI
+PDWORD
+WINAPI
 GetSidSubAuthority(PSID pSid,
                    DWORD nSubAuthority)
 {
@@ -1546,7 +1497,8 @@ GetSidSubAuthority(PSID pSid,
 /*
  * @implemented
  */
-PUCHAR WINAPI
+PUCHAR
+WINAPI
 GetSidSubAuthorityCount(PSID pSid)
 {
     return RtlSubAuthorityCountSid(pSid);
@@ -1556,7 +1508,8 @@ GetSidSubAuthorityCount(PSID pSid)
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 InitializeSid(PSID Sid,
               PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
               BYTE nSubAuthorityCount)
@@ -1579,7 +1532,8 @@ InitializeSid(PSID Sid,
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 IsValidSid(PSID pSid)
 {
     return (BOOL)RtlValidSid(pSid);
@@ -1589,7 +1543,8 @@ IsValidSid(PSID pSid)
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 ConvertSidToStringSidW(PSID Sid,
                        LPWSTR *StringSid)
 {
@@ -1643,7 +1598,8 @@ ConvertSidToStringSidW(PSID Sid,
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 ConvertSidToStringSidA(PSID Sid,
                        LPSTR *StringSid)
 {
@@ -1687,7 +1643,8 @@ ConvertSidToStringSidA(PSID Sid,
 /*
  * @unimplemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 EqualDomainSid(IN PSID pSid1,
                IN PSID pSid2,
                OUT BOOL* pfEqual)
@@ -1700,7 +1657,8 @@ EqualDomainSid(IN PSID pSid1,
 /*
  * @unimplemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 GetWindowsAccountDomainSid(IN PSID pSid,
                            OUT PSID ppDomainSid,
                            IN OUT DWORD* cbSid)
@@ -1713,7 +1671,8 @@ GetWindowsAccountDomainSid(IN PSID pSid,
 /*
  * @unimplemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
                    IN PSID DomainSid  OPTIONAL,
                    OUT PSID pSid,
@@ -1787,7 +1746,8 @@ CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
 /*
  * @unimplemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 IsWellKnownSid(IN PSID pSid,
                IN WELL_KNOWN_SID_TYPE WellKnownSidType)
 {
@@ -1810,7 +1770,8 @@ IsWellKnownSid(IN PSID pSid,
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 ConvertStringSidToSidA(IN LPCSTR StringSid,
                        OUT PSID* sid)
 {
@@ -1879,7 +1840,8 @@ static const RECORD SidTable[] =
 /*
  * @implemented
  */
-BOOL WINAPI
+BOOL
+WINAPI
 ConvertStringSidToSidW(IN LPCWSTR StringSid,
                        OUT PSID* sid)
 {
@@ -1890,43 +1852,43 @@ ConvertStringSidToSidW(IN LPCWSTR StringSid,
 
     TRACE("%s %p\n", debugstr_w(StringSid), sid);
 
-       if (!StringSid)
-       {
-               SetLastError(ERROR_INVALID_SID);
-               return FALSE;
-       }
-       for (i = 0; i < sizeof(SidTable) / sizeof(SidTable[0]) - 1; i++)
-       {
-               if (wcscmp(StringSid, SidTable[i].key) == 0)
-               {
-                       WELL_KNOWN_SID_TYPE knownSid = (WELL_KNOWN_SID_TYPE)SidTable[i].value;
-                       size = SECURITY_MAX_SID_SIZE;
-                       *sid = LocalAlloc(0, size);
-                       if (!*sid)
-                       {
-                               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                               return FALSE;
-                       }
-                       ret = CreateWellKnownSid(
-                               knownSid,
-                               NULL,
-                               *sid,
-                               &size);
-                       if (!ret)
-                       {
-                               SetLastError(ERROR_INVALID_SID);
-                               LocalFree(*sid);
-                       }
-                       return ret;
-               }
-       }
-
-       /* That's probably a string S-R-I-S-S... */
-       if (StringSid[0] != 'S' || StringSid[1] != '-')
-       {
-               SetLastError(ERROR_INVALID_SID);
-               return FALSE;
-       }
+    if (!StringSid)
+    {
+        SetLastError(ERROR_INVALID_SID);
+        return FALSE;
+    }
+
+    for (i = 0; i < sizeof(SidTable) / sizeof(SidTable[0]) - 1; i++)
+    {
+        if (wcscmp(StringSid, SidTable[i].key) == 0)
+        {
+            WELL_KNOWN_SID_TYPE knownSid = (WELL_KNOWN_SID_TYPE)SidTable[i].value;
+            size = SECURITY_MAX_SID_SIZE;
+            *sid = LocalAlloc(0, size);
+            if (!*sid)
+            {
+                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                return FALSE;
+            }
+            ret = CreateWellKnownSid(knownSid,
+                                     NULL,
+                                     *sid,
+                                     &size);
+            if (!ret)
+            {
+                SetLastError(ERROR_INVALID_SID);
+                LocalFree(*sid);
+            }
+            return ret;
+        }
+    }
+
+    /* That's probably a string S-R-I-S-S... */
+    if (StringSid[0] != 'S' || StringSid[1] != '-')
+    {
+        SetLastError(ERROR_INVALID_SID);
+        return FALSE;
+    }
 
     cBytes = ComputeStringSidSize(StringSid);
     pisid = (SID*)LocalAlloc( 0, cBytes );
@@ -2005,5 +1967,4 @@ lend:
     return ret;
 }
 
-
 /* EOF */
index e830308..c0afdbf 100644 (file)
 
 /* FUNCTIONS ******************************************************************/
 
-VOID
-NTAPI
-SetRosSpecificInfo(IN LPOSVERSIONINFOEXW VersionInformation)
-{
-    CHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD)];
-    PKEY_VALUE_PARTIAL_INFORMATION kvpInfo = (PVOID)Buffer;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    DWORD ReportAsWorkstation = 0;
-    HANDLE hKey;
-    DWORD dwSize;
-    NTSTATUS Status;
-    UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ReactOS\\Settings\\Version");
-    UNICODE_STRING ValName = RTL_CONSTANT_STRING(L"ReportAsWorkstation");
-
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &KeyName,
-                               OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
-                               NULL,
-                               NULL);
-
-    /* Don't change anything if the key doesn't exist */
-    Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
-    if (NT_SUCCESS(Status))
-    {
-        /* Get the value from the registry and make sure it's a 32-bit value */
-        Status = NtQueryValueKey(hKey,
-                                 &ValName,
-                                 KeyValuePartialInformation,
-                                 kvpInfo,
-                                 sizeof(Buffer),
-                                 &dwSize);
-        if ((NT_SUCCESS(Status)) &&
-            (kvpInfo->Type == REG_DWORD) &&
-            (kvpInfo->DataLength == sizeof(DWORD)))
-        {
-            /* Is the value set? */
-            ReportAsWorkstation = *(PULONG)kvpInfo->Data;
-            if ((VersionInformation->wProductType == VER_NT_SERVER) &&
-                (ReportAsWorkstation))
-            {
-                /* It is, modify the product type to report a workstation */
-                VersionInformation->wProductType = VER_NT_WORKSTATION;
-                DPRINT1("We modified the reported OS from NtProductServer to NtProductWinNt\n");
-            }
-        }
-
-        /* Close the handle */
-        NtClose(hKey);
-     }
-}
-
 /*
  * @implemented
  */
@@ -104,9 +53,6 @@ GetVersionExW(IN LPOSVERSIONINFOW lpVersionInformation)
         {
             lpVersionInformationEx = (PVOID)lpVersionInformation;
             lpVersionInformationEx->wReserved = 0;
-
-            /* ReactOS specific changes */
-            SetRosSpecificInfo(lpVersionInformationEx);
         }
 
         return TRUE;
index 219f4f9..50ae272 100644 (file)
@@ -28,5 +28,7 @@ target_link_libraries(netapi32 wine)
 
 add_importlibs(netapi32 iphlpapi ws2_32 advapi32 msvcrt kernel32 ntdll)
 
+add_delay_importlibs(netapi32 samlib)
+
 add_cd_file(TARGET netapi32 DESTINATION reactos/system32 FOR all)
 
index e125de5..a02d1cc 100644 (file)
 #include "wine/debug.h"
 #include "wine/unicode.h"
 
+#define NTOS_MODE_USER
+#include <ndk/rtlfuncs.h>
+#include "ntsam.h"
+#include "netapi32.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
 
+
+typedef struct _ENUM_CONTEXT
+{
+    SAM_HANDLE ServerHandle;
+    SAM_HANDLE BuiltinDomainHandle;
+    SAM_HANDLE AccountDomainHandle;
+
+    SAM_ENUMERATE_HANDLE EnumerationContext;
+    PSAM_RID_ENUMERATION Buffer;
+    ULONG Returned;
+    ULONG Index;
+    BOOLEAN BuiltinDone;
+
+} ENUM_CONTEXT, *PENUM_CONTEXT;
+
+static SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
+
+
+static
+NTSTATUS
+GetAccountDomainSid(PSID *AccountDomainSid)
+{
+    PPOLICY_ACCOUNT_DOMAIN_INFO AccountDomainInfo = NULL;
+    LSA_OBJECT_ATTRIBUTES ObjectAttributes;
+    LSA_HANDLE PolicyHandle = NULL;
+    ULONG Length = 0;
+    NTSTATUS Status;
+
+    memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES));
+
+    Status = LsaOpenPolicy(NULL,
+                           &ObjectAttributes,
+                           POLICY_VIEW_LOCAL_INFORMATION,
+                           &PolicyHandle);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsaOpenPolicy failed (Status %08lx)\n", Status);
+        return Status;
+    }
+
+    Status = LsaQueryInformationPolicy(PolicyHandle,
+                                       PolicyAccountDomainInformation,
+                                       (PVOID *)&AccountDomainInfo);
+    if (!NT_SUCCESS(Status))
+    {
+        ERR("LsaQueryInformationPolicy failed (Status %08lx)\n", Status);
+        goto done;
+    }
+
+    Length = RtlLengthSid(AccountDomainInfo->DomainSid);
+
+    *AccountDomainSid = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
+    if (*AccountDomainSid == NULL)
+    {
+        ERR("Failed to allocate SID\n");
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto done;
+    }
+
+    memcpy(*AccountDomainSid, AccountDomainInfo->DomainSid, Length);
+
+done:
+    if (AccountDomainInfo != NULL)
+        LsaFreeMemory(AccountDomainInfo);
+
+    LsaClose(PolicyHandle);
+
+    return Status;
+}
+
+
+static
+NTSTATUS
+GetBuiltinDomainSid(PSID *BuiltinDomainSid)
+{
+    PSID Sid = NULL;
+    PULONG Ptr;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    *BuiltinDomainSid = NULL;
+
+    Sid = RtlAllocateHeap(RtlGetProcessHeap(),
+                          0,
+                          RtlLengthRequiredSid(1));
+    if (Sid == NULL)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    Status = RtlInitializeSid(Sid,
+                              &NtAuthority,
+                              1);
+    if (!NT_SUCCESS(Status))
+        goto done;
+
+    Ptr = RtlSubAuthoritySid(Sid, 0);
+    *Ptr = SECURITY_BUILTIN_DOMAIN_RID;
+
+    *BuiltinDomainSid = Sid;
+
+done:
+    if (!NT_SUCCESS(Status))
+    {
+        if (Sid != NULL)
+            RtlFreeHeap(RtlGetProcessHeap(), 0, Sid);
+    }
+
+    return Status;
+}
+
+
 /************************************************************
  *                NetLocalGroupAdd  (NETAPI32.@)
  */
@@ -129,11 +243,236 @@ NET_API_STATUS WINAPI NetLocalGroupEnum(
     LPDWORD totalentries,
     PDWORD_PTR resumehandle)
 {
+    PSAM_RID_ENUMERATION CurrentAlias;
+    PENUM_CONTEXT EnumContext = NULL;
+    PSID DomainSid = NULL;
+    ULONG i;
+    SAM_HANDLE AliasHandle = NULL;
+    PALIAS_GENERAL_INFORMATION AliasInfo = NULL;
+
+    NET_API_STATUS ApiStatus = NERR_Success;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+
     FIXME("(%s %d %p %d %p %p %p) stub!\n", debugstr_w(servername),
           level, bufptr, prefmaxlen, entriesread, totalentries, resumehandle);
+
     *entriesread = 0;
     *totalentries = 0;
-    return NERR_Success;
+    *bufptr = NULL;
+
+    if (resumehandle != NULL && *resumehandle != 0)
+    {
+        EnumContext = (PENUM_CONTEXT)resumehandle;
+    }
+    else
+    {
+        ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext);
+        if (ApiStatus != NERR_Success)
+            goto done;
+
+        EnumContext->EnumerationContext = 0;
+        EnumContext->Buffer = NULL;
+        EnumContext->Returned = 0;
+        EnumContext->Index = 0;
+        EnumContext->BuiltinDone = FALSE;
+
+        Status = SamConnect(NULL,
+                            &EnumContext->ServerHandle,
+                            SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
+                            NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("SamConnect failed (Status %08lx)\n", Status);
+            ApiStatus = NetpNtStatusToApiStatus(Status);
+            goto done;
+        }
+
+        Status = GetAccountDomainSid(&DomainSid);
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
+            ApiStatus = NetpNtStatusToApiStatus(Status);
+            goto done;
+        }
+
+        Status = SamOpenDomain(EnumContext->ServerHandle,
+                               DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
+                               DomainSid,
+                               &EnumContext->AccountDomainHandle);
+
+        RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
+
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("SamOpenDomain failed (Status %08lx)\n", Status);
+            ApiStatus = NetpNtStatusToApiStatus(Status);
+            goto done;
+        }
+
+        Status = GetBuiltinDomainSid(&DomainSid);
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
+            ApiStatus = NetpNtStatusToApiStatus(Status);
+            goto done;
+        }
+
+        Status = SamOpenDomain(EnumContext->ServerHandle,
+                               DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
+                               DomainSid,
+                               &EnumContext->BuiltinDomainHandle);
+
+        RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
+
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("SamOpenDomain failed (Status %08lx)\n", Status);
+            ApiStatus = NetpNtStatusToApiStatus(Status);
+            goto done;
+        }
+    }
+
+
+    while (TRUE)
+    {
+
+        if (EnumContext->Index >= EnumContext->Returned)
+        {
+            if (EnumContext->BuiltinDone == TRUE)
+            {
+                ApiStatus = NERR_Success;
+                goto done;
+            }
+
+            TRACE("Calling SamEnumerateAliasesInDomain\n");
+
+            Status = SamEnumerateAliasesInDomain(EnumContext->BuiltinDomainHandle,
+                                                 &EnumContext->EnumerationContext,
+                                                 (PVOID *)&EnumContext->Buffer,
+                                                 prefmaxlen,
+                                                 &EnumContext->Returned);
+
+            TRACE("SamEnumerateAliasesInDomain returned (Status %08lx)\n", Status);
+            if (!NT_SUCCESS(Status))
+            {
+                ERR("SamEnumerateAliasesInDomain failed (Status %08lx)\n", Status);
+                ApiStatus = NetpNtStatusToApiStatus(Status);
+                goto done;
+            }
+
+            if (Status == STATUS_MORE_ENTRIES)
+            {
+                ApiStatus = NERR_BufTooSmall;
+                goto done;
+            }
+            else
+            {
+                EnumContext->BuiltinDone = TRUE;
+            }
+        }
+
+        TRACE("EnumContext: %lu\n", EnumContext);
+        TRACE("EnumContext->Returned: %lu\n", EnumContext->Returned);
+        TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer);
+
+        /* Get a pointer to the current alias */
+        CurrentAlias = &EnumContext->Buffer[EnumContext->Index];
+
+        TRACE("RID: %lu\n", CurrentAlias->RelativeId);
+
+        Status = SamOpenAlias(EnumContext->BuiltinDomainHandle,
+                              ALIAS_READ_INFORMATION,
+                              CurrentAlias->RelativeId,
+                              &AliasHandle);
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("SamOpenAlias failed (Status %08lx)\n", Status);
+            ApiStatus = NetpNtStatusToApiStatus(Status);
+            goto done;
+        }
+
+        Status = SamQueryInformationAlias(AliasHandle,
+                                          AliasGeneralInformation,
+                                          (PVOID *)&AliasInfo);
+        if (!NT_SUCCESS(Status))
+        {
+            ERR("SamQueryInformationAlias failed (Status %08lx)\n", Status);
+            ApiStatus = NetpNtStatusToApiStatus(Status);
+            goto done;
+        }
+
+        SamCloseHandle(AliasHandle);
+        AliasHandle = NULL;
+
+        TRACE("Name: %S\n", AliasInfo->Name.Buffer);
+        TRACE("Comment: %S\n", AliasInfo->AdminComment.Buffer);
+
+
+        if (AliasInfo != NULL)
+        {
+            if (AliasInfo->Name.Buffer != NULL)
+                SamFreeMemory(AliasInfo->Name.Buffer);
+
+            if (AliasInfo->AdminComment.Buffer != NULL)
+                SamFreeMemory(AliasInfo->AdminComment.Buffer);
+
+            SamFreeMemory(AliasInfo);
+            AliasInfo = NULL;
+        }
+
+
+        EnumContext->Index++;
+    }
+
+
+done:
+    if (resumehandle == NULL || ApiStatus != ERROR_MORE_DATA)
+    {
+        if (EnumContext != NULL)
+        {
+            if (EnumContext->BuiltinDomainHandle != NULL)
+                SamCloseHandle(EnumContext->BuiltinDomainHandle);
+
+            if (EnumContext->AccountDomainHandle != NULL)
+                SamCloseHandle(EnumContext->AccountDomainHandle);
+
+            if (EnumContext->ServerHandle != NULL)
+                SamCloseHandle(EnumContext->ServerHandle);
+
+            if (EnumContext->Buffer != NULL)
+            {
+                for (i = 0; i < EnumContext->Returned; i++)
+                {
+                    SamFreeMemory(EnumContext->Buffer[i].Name.Buffer);
+                }
+
+                SamFreeMemory(EnumContext->Buffer);
+            }
+
+            NetApiBufferFree(EnumContext);
+            EnumContext = NULL;
+        }
+    }
+
+    if (AliasHandle != NULL)
+        SamCloseHandle(AliasHandle);
+
+    if (AliasInfo != NULL)
+    {
+        if (AliasInfo->Name.Buffer != NULL)
+            SamFreeMemory(AliasInfo->Name.Buffer);
+
+        if (AliasInfo->AdminComment.Buffer != NULL)
+            SamFreeMemory(AliasInfo->AdminComment.Buffer);
+
+        SamFreeMemory(AliasInfo);
+    }
+
+    if (resumehandle != NULL)
+        *resumehandle = (DWORD_PTR)EnumContext;
+
+    return ApiStatus;
 }
 
 /************************************************************
index fb4468f..a0a8347 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#define WIN32_NO_STATUS
 #include "config.h"
 
 #include "wine/debug.h"
 #include "lm.h"
 #include "netbios.h"
 
+#define NTOS_MODE_USER
+#include <ndk/rtlfuncs.h>
+#include "netapi32.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(netbios);
 
 static HMODULE NETAPI32_hModule;
@@ -211,6 +216,13 @@ DWORD WINAPI NetpNetBiosStatusToApiStatus(DWORD nrc)
     return ret;
 }
 
+NET_API_STATUS
+WINAPI
+NetpNtStatusToApiStatus(NTSTATUS Status)
+{
+    return RtlNtStatusToDosError(Status);
+}
+
 NET_API_STATUS WINAPI NetUseEnum(LMSTR server, DWORD level, LPBYTE* bufptr, DWORD prefmaxsize,
                           LPDWORD entriesread, LPDWORD totalentries, LPDWORD resumehandle)
 {
diff --git a/dll/win32/netapi32/netapi32.h b/dll/win32/netapi32/netapi32.h
new file mode 100644 (file)
index 0000000..f7a0a7a
--- /dev/null
@@ -0,0 +1,10 @@
+
+#ifndef __WINE_NETAPI32_H__
+#define __WINE_NETAPI32_H__
+
+NET_API_STATUS
+WINAPI
+NetpNtStatusToApiStatus(NTSTATUS Status);
+
+
+#endif
\ No newline at end of file
index 6470280..1fb5ccf 100644 (file)
 @ stub NetpNetBiosReset
 @ stub NetpNetBiosSend
 @ stdcall NetpNetBiosStatusToApiStatus(long)
-@ stub NetpNtStatusToApiStatus
+@ stdcall NetpNtStatusToApiStatus(long)
 @ stub NetpOpenConfigData
 @ stub NetpPackString
 @ stub NetpReleasePrivilege
index fc885fd..68b886a 100644 (file)
@@ -155,6 +155,7 @@ SamrShutdownSamServer(IN SAMPR_HANDLE ServerHandle)
     return STATUS_NOT_IMPLEMENTED;
 }
 
+
 /* Function 5 */
 NTSTATUS
 NTAPI
@@ -264,6 +265,7 @@ SamrLookupDomainInSamServer(IN SAMPR_HANDLE ServerHandle,
     return Status;
 }
 
+
 /* Function 6 */
 NTSTATUS
 NTAPI
@@ -3868,17 +3870,24 @@ SampQueryAliasGeneral(PSAM_DB_OBJECT AliasObject,
                             L"Members",
                             KEY_READ,
                             &MembersKeyHandle);
-    if (!NT_SUCCESS(Status))
+    if (NT_SUCCESS(Status))
     {
-        TRACE("Status 0x%08lx\n", Status);
-        goto done;
+        /* Retrieve the number of members of the alias */
+        Status = SampRegQueryKeyInfo(MembersKeyHandle,
+                                     NULL,
+                                     &InfoBuffer->General.MemberCount);
+        if (!NT_SUCCESS(Status))
+        {
+            TRACE("Status 0x%08lx\n", Status);
+            goto done;
+        }
     }
-
-    /* Retrieve the number of members of the alias */
-    Status = SampRegQueryKeyInfo(MembersKeyHandle,
-                                 NULL,
-                                 &InfoBuffer->General.MemberCount);
-    if (!NT_SUCCESS(Status))
+    else if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+    {
+        InfoBuffer->General.MemberCount = 0;
+        Status = STATUS_SUCCESS;
+    }
+    else
     {
         TRACE("Status 0x%08lx\n", Status);
         goto done;
index e81509c..b2e8210 100644 (file)
@@ -4,7 +4,7 @@
  * PURPOSE:         Runtime code
  * FILE:            lib/rtl/version.c
  * PROGRAMERS:      Filip Navara
- *                  Hermes BELUSCA - MAITO
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
  */
 
 /* INCLUDES *****************************************************************/
@@ -18,9 +18,7 @@
 
 NTSTATUS
 NTAPI
-RtlGetVersion(
-    OUT PRTL_OSVERSIONINFOW lpVersionInformation
-    );
+RtlGetVersion(OUT PRTL_OSVERSIONINFOW lpVersionInformation);
 
 /* FUNCTIONS ****************************************************************/
 
@@ -54,11 +52,9 @@ RtlpVerCompare(ULONG left, ULONG right, UCHAR condition)
 */
 NTSTATUS
 NTAPI
-RtlVerifyVersionInfo(
-    IN PRTL_OSVERSIONINFOEXW VersionInfo,
-    IN ULONG TypeMask,
-    IN ULONGLONG ConditionMask
-    )
+RtlVerifyVersionInfo(IN PRTL_OSVERSIONINFOEXW VersionInfo,
+                     IN ULONG TypeMask,
+                     IN ULONGLONG ConditionMask)
 {
     RTL_OSVERSIONINFOEXW ver;
     NTSTATUS status;
index ae5d496..27660f7 100644 (file)
@@ -678,7 +678,7 @@ MmCreatePeb(IN PEPROCESS Process,
         Peb->OSMajorVersion = NtMajorVersion;
         Peb->OSMinorVersion = NtMinorVersion;
         Peb->OSBuildNumber = (USHORT)(NtBuildNumber & 0x3FFF);
-        Peb->OSPlatformId = 2; /* VER_PLATFORM_WIN32_NT */
+        Peb->OSPlatformId = VER_PLATFORM_WIN32_NT;
         Peb->OSCSDVersion = (USHORT)CmNtCSDVersion;
 
         //
index 2ad6931..d7c09b1 100644 (file)
@@ -29,51 +29,55 @@ ULONG
 NTAPI
 RtlGetNtGlobalFlags(VOID)
 {
-       return(NtGlobalFlag);
+    return NtGlobalFlag;
 }
 
-
 /*
 * @implemented
 */
 NTSTATUS NTAPI
 RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
 {
-   LONG i;
-   ULONG MaxLength;
-   if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOW) ||
-       lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
-   {
-      lpVersionInformation->dwMajorVersion = NtMajorVersion;
-      lpVersionInformation->dwMinorVersion = NtMinorVersion;
-      lpVersionInformation->dwBuildNumber = NtBuildNumber;
-      lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
-      RtlZeroMemory(lpVersionInformation->szCSDVersion, sizeof(lpVersionInformation->szCSDVersion));
-      if(((CmNtCSDVersion >> 8) & 0xFF) != 0)
-      {
-        MaxLength = (sizeof(lpVersionInformation->szCSDVersion) / sizeof(lpVersionInformation->szCSDVersion[0])) - 1;
-        i = _snwprintf(lpVersionInformation->szCSDVersion,
-                       MaxLength,
-                       L"Service Pack %d",
-                       ((CmNtCSDVersion >> 8) & 0xFF));
-        if (i < 0)
+    LONG i;
+    ULONG MaxLength;
+
+    if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOW) ||
+        lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
+    {
+        lpVersionInformation->dwMajorVersion = NtMajorVersion;
+        lpVersionInformation->dwMinorVersion = NtMinorVersion;
+        lpVersionInformation->dwBuildNumber = NtBuildNumber;
+        lpVersionInformation->dwPlatformId = VER_PLATFORM_WIN32_NT;
+        RtlZeroMemory(lpVersionInformation->szCSDVersion, sizeof(lpVersionInformation->szCSDVersion));
+
+        if(((CmNtCSDVersion >> 8) & 0xFF) != 0)
+        {
+            MaxLength = (sizeof(lpVersionInformation->szCSDVersion) / sizeof(lpVersionInformation->szCSDVersion[0])) - 1;
+            i = _snwprintf(lpVersionInformation->szCSDVersion,
+                           MaxLength,
+                           L"Service Pack %d",
+                           ((CmNtCSDVersion >> 8) & 0xFF));
+            if (i < 0)
+            {
+                /* Null-terminate if it was overflowed */
+                lpVersionInformation->szCSDVersion[MaxLength] = L'\0';
+            }
+        }
+
+        if (lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW))
         {
-           /* null-terminate if it was overflowed */
-           lpVersionInformation->szCSDVersion[MaxLength] = L'\0';
+            PRTL_OSVERSIONINFOEXW InfoEx = (PRTL_OSVERSIONINFOEXW)lpVersionInformation;
+            InfoEx->wServicePackMajor = (USHORT)(CmNtCSDVersion >> 8) & 0xFF;
+            InfoEx->wServicePackMinor = (USHORT)(CmNtCSDVersion & 0xFF);
+            InfoEx->wSuiteMask = (USHORT)(SharedUserData->SuiteMask & 0xFFFF);
+            InfoEx->wProductType = SharedUserData->NtProductType;
+            InfoEx->wReserved = 0;
         }
-      }
-      if (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXW))
-      {
-         RTL_OSVERSIONINFOEXW *InfoEx = (RTL_OSVERSIONINFOEXW *)lpVersionInformation;
-         InfoEx->wServicePackMajor = (USHORT)(CmNtCSDVersion >> 8) & 0xFF;
-         InfoEx->wServicePackMinor = (USHORT)(CmNtCSDVersion & 0xFF);
-         InfoEx->wSuiteMask = (USHORT)(SharedUserData->SuiteMask & 0xFFFF);
-         InfoEx->wProductType = SharedUserData->NtProductType;
-      }
 
-      return STATUS_SUCCESS;
-   }
+        return STATUS_SUCCESS;
+    }
 
-   return STATUS_INVALID_PARAMETER;
+    return STATUS_INVALID_PARAMETER;
 }
 
+/* EOF */
index 25e4df5..38a2a0f 100644 (file)
@@ -11,6 +11,10 @@ if(USE_DIBLIB)
     add_subdirectory(gdi/diblib)
 endif()
 
+if(USE_NEW_CURSORICON)
+    add_definitions(-DNEW_CURSORICON)
+endif()
+
 add_subdirectory(gdi/gdi32)
 add_subdirectory(reactx)
 add_subdirectory(user/consrv)
@@ -190,7 +194,6 @@ else()
 endif()
 
 if(USE_NEW_CURSORICON)
-    add_definitions(-DNEW_CURSORICON)
     list(APPEND SOURCE user/ntuser/cursoricon_new.c)
 else()
     list(APPEND SOURCE user/ntuser/cursoricon.c)
index 184f81f..0e4ba75 100644 (file)
@@ -48,14 +48,17 @@ list(APPEND SOURCE
 
 add_library(gdi32 SHARED ${SOURCE})
 
-set_module_type(gdi32 win32dll UNICODE)
+set_module_type(gdi32
+    win32dll
+    ENTRYPOINT DllMain 12
+    UNICODE)
 
 target_link_libraries(gdi32
     win32ksys
     dxguid
     ${PSEH_LIB})
 
-add_importlibs(gdi32 user32 advapi32 msvcrt kernel32 ntdll)
+add_importlibs(gdi32 user32 advapi32 kernel32 ntdll)
 add_pch(gdi32 include/precomp.h)
 add_cd_file(TARGET gdi32 DESTINATION reactos/system32 FOR all)
 
index 84f315b..5e7bf2c 100644 (file)
@@ -1659,8 +1659,8 @@ NtUserDestroyAcceleratorTable(
 BOOL
 NTAPI
 NtUserDestroyCursor(
-  HANDLE Handle,
-  DWORD Unknown);
+  _In_  HANDLE Handle,
+  _In_  BOOL bForce);
 
 DWORD
 NTAPI
@@ -1818,14 +1818,6 @@ NtUserFillWindow(
   HDC  hDC,
   HBRUSH hBrush);
 
-HICON
-NTAPI
-NtUserFindExistingCursorIcon(
-  HMODULE hModule,
-  HRSRC hRsrc,
-  LONG cx,
-  LONG cy);
-
 HWND
 NTAPI
 NtUserFindWindowEx(
@@ -1998,12 +1990,12 @@ NtUserGetGUIThreadInfo(
 BOOL
 NTAPI
 NtUserGetIconInfo(
-   HANDLE hCurIcon,
-   PICONINFO IconInfo,
-   PUNICODE_STRING lpInstName,
-   PUNICODE_STRING lpResName,
-   LPDWORD pbpp,
-   BOOL bInternal);
+   _In_      HANDLE hCurIcon,
+   _Out_opt_ PICONINFO IconInfo,
+   _Out_opt_ PUNICODE_STRING lpInstName,
+   _Out_opt_ PUNICODE_STRING lpResName,
+   _Out_opt_ LPDWORD pbpp,
+   _In_      BOOL bInternal);
 
 BOOL
 NTAPI
@@ -2743,9 +2735,17 @@ BOOL
 NTAPI
 NtUserSetCursorIconData(
   _In_ HCURSOR hCursor,
-  _In_ HINSTANCE hinst,
-  _In_ HRSRC hrsrc,
+  _In_ PUNICODE_STRING pustrModule,
+  _In_ PUNICODE_STRING puSrcName,
   _In_ PICONINFO pii);
+  
+HICON
+NTAPI
+NtUserFindExistingCursorIcon(
+  _In_  PUNICODE_STRING pustrModule,
+  _In_  PUNICODE_STRING pustrRsrc,
+  _In_  LONG cxDesired,
+  _In_  LONG cyDesired);
 #else
 BOOL
 NTAPI
@@ -2756,6 +2756,14 @@ NtUserSetCursorIconData(
   HMODULE hModule,
   HRSRC hRsrc,
   HRSRC hGroupRsrc);
+  
+HICON
+NTAPI
+NtUserFindExistingCursorIcon(
+  HMODULE hModule,
+  HRSRC hRsrc,
+  LONG cx,
+  LONG cy);
 #endif
 
 DWORD
index b54bc9b..27a5aad 100644 (file)
@@ -88,8 +88,9 @@ typedef struct
 
 typedef struct
 {   union
-    { ICONRESDIR icon;
-      CURSORDIR  cursor;
+    { 
+        ICONRESDIR icon;
+        CURSORDIR  cursor;
     } ResInfo;
     WORD   wPlanes;
     WORD   wBitCount;
index afba9eb..209dccc 100644 (file)
@@ -124,7 +124,7 @@ LookupFnIdToiCls(int FnId, int *iCls )
 _Must_inspect_result_
 NTSTATUS
 NTAPI
-CaptureUnicodeStringOrAtom(
+ProbeAndCaptureUnicodeStringOrAtom(
     _Out_ PUNICODE_STRING pustrOut,
     __in_data_source(USER_MODE) _In_ PUNICODE_STRING pustrUnsafe)
 {
@@ -2294,7 +2294,7 @@ NtUserUnregisterClass(
     NTSTATUS Status;
     BOOL Ret;
 
-    Status = CaptureUnicodeStringOrAtom(&SafeClassName, ClassNameOrAtom);
+    Status = ProbeAndCaptureUnicodeStringOrAtom(&SafeClassName, ClassNameOrAtom);
     if (!NT_SUCCESS(Status))
     {
         ERR("Error capturing the class name\n");
@@ -2346,7 +2346,7 @@ NtUserGetClassInfo(
     }
     _SEH2_END;
 
-    Status = CaptureUnicodeStringOrAtom(&SafeClassName, ClassName);
+    Status = ProbeAndCaptureUnicodeStringOrAtom(&SafeClassName, ClassName);
     if (!NT_SUCCESS(Status))
     {
         ERR("Error capturing the class name\n");
@@ -2480,7 +2480,7 @@ NtUserGetWOWClass(
     RTL_ATOM ClassAtom = 0;
     NTSTATUS Status;
 
-    Status = CaptureUnicodeStringOrAtom(&SafeClassName, ClassName);
+    Status = ProbeAndCaptureUnicodeStringOrAtom(&SafeClassName, ClassName);
     if (!NT_SUCCESS(Status))
     {
         ERR("Error capturing the class name\n");
index f2d7978..901f2b4 100644 (file)
@@ -59,4 +59,11 @@ IntCheckProcessDesktopClasses(IN PDESKTOP Desktop,
 
 ULONG_PTR FASTCALL UserGetCPD(PVOID,GETCPD,ULONG_PTR);
 
+_Must_inspect_result_
+NTSTATUS
+NTAPI
+ProbeAndCaptureUnicodeStringOrAtom(
+    _Out_ PUNICODE_STRING pustrOut,
+    __in_data_source(USER_MODE) _In_ PUNICODE_STRING pustrUnsafe);
+
 /* EOF */
index 7ba56db..84d8c76 100644 (file)
@@ -204,7 +204,7 @@ IntFindExistingCurIconObject(HMODULE hModule,
 }
 
 PCURICON_OBJECT
-IntCreateCurIconHandle()
+IntCreateCurIconHandle(DWORD dwNumber)
 {
     PCURICON_OBJECT CurIcon;
     HANDLE hCurIcon;
@@ -613,8 +613,8 @@ NtUserClipCursor(
 BOOL
 APIENTRY
 NtUserDestroyCursor(
-    HANDLE hCurIcon,
-    DWORD Unknown)
+  _In_  HANDLE hCurIcon,
+  _In_  BOOL bForce)
 {
     PCURICON_OBJECT CurIcon;
     BOOL ret;
index 3bf5e19..842392d 100644 (file)
@@ -22,8 +22,8 @@ typedef struct _CURICON_OBJECT
   LIST_ENTRY ListEntry;
   HANDLE Self;
   LIST_ENTRY ProcessList;
-  HMODULE hModule;
-  HRSRC hRsrc;
+  UNICODE_STRING ustrModule;
+  UNICODE_STRING ustrRsrc;
   SIZE Size;
   BYTE Shadow;
   BOOL bIcon;
@@ -88,7 +88,7 @@ typedef struct _SYSTEM_CURSORINFO
 } SYSTEM_CURSORINFO, *PSYSTEM_CURSORINFO;
 
 BOOL InitCursorImpl(VOID);
-PCURICON_OBJECT IntCreateCurIconHandle(VOID);
+PCURICON_OBJECT IntCreateCurIconHandle(DWORD dwNumber);
 VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process);
 
 BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth,
index 0c772a2..e5d25ba 100644 (file)
@@ -169,47 +169,61 @@ ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
     return TRUE;
 }
 
-PCURICON_OBJECT FASTCALL
-IntFindExistingCurIconObject(HMODULE hModule,
-                             HRSRC hRsrc, LONG cx, LONG cy)
+static
+PCURICON_OBJECT
+FASTCALL
+IntFindExistingCurIconObject(
+    PUNICODE_STRING pustrModule,
+    PUNICODE_STRING pustrRsrc,
+    FINDEXISTINGCURICONPARAM* param)
 {
     PCURICON_OBJECT CurIcon;
 
     LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
     {
-
-        // if (NT_SUCCESS(UserReferenceObjectByPointer(Object, otCursorIcon))) // <- huh????
-//      UserReferenceObject(  CurIcon);
-//      {
-        if ((CurIcon->hModule == hModule) && (CurIcon->hRsrc == hRsrc))
+        /* See if we are looking for an icon or a cursor */
+        if(CurIcon->bIcon != param->bIcon)
+            continue;
+        /* See if module names match */
+        if(RtlCompareUnicodeString(pustrModule, &CurIcon->ustrModule, TRUE) == 0)
         {
-            if (cx && ((cx != CurIcon->Size.cx) || (cy != CurIcon->Size.cy)))
+            /* They do. Now see if this is the same resource */
+            if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer) && IS_INTRESOURCE(pustrRsrc->Buffer))
             {
-//               UserDereferenceObject(CurIcon);
-                continue;
+                if(CurIcon->ustrRsrc.Buffer != pustrRsrc->Buffer)
+                    continue;
             }
-            if (! ReferenceCurIconByProcess(CurIcon))
+            else if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer) || IS_INTRESOURCE(pustrRsrc->Buffer))
+                continue;
+            else if(RtlCompareUnicodeString(pustrRsrc, &CurIcon->ustrRsrc, TRUE) != 0)
+                continue;
+            
+            if ((param->cx == CurIcon->Size.cx) &&(param->cy == CurIcon->Size.cy))
             {
-                return NULL;
-            }
+                if (! ReferenceCurIconByProcess(CurIcon))
+                {
+                    return NULL;
+                }
 
-            return CurIcon;
+                return CurIcon;
+            }
         }
-//      }
-//      UserDereferenceObject(CurIcon);
-
     }
 
     return NULL;
 }
 
 PCURICON_OBJECT
-IntCreateCurIconHandle()
+IntCreateCurIconHandle(DWORD dwNumber)
 {
     PCURICON_OBJECT CurIcon;
+    BOOLEAN bIcon = dwNumber == 0;
     HANDLE hCurIcon;
+    
+    if(dwNumber == 0)
+        dwNumber = 1;
 
-    CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
+    CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, FIELD_OFFSET(CURICON_OBJECT, aFrame[dwNumber]));
 
     if (!CurIcon)
     {
@@ -218,6 +232,7 @@ IntCreateCurIconHandle()
     }
 
     CurIcon->Self = hCurIcon;
+    CurIcon->bIcon = bIcon;
     InitializeListHead(&CurIcon->ProcessList);
 
     if (! ReferenceCurIconByProcess(CurIcon))
@@ -234,7 +249,7 @@ IntCreateCurIconHandle()
 }
 
 BOOLEAN FASTCALL
-IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
+IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi, BOOLEAN bForce)
 {
     PSYSTEM_CURSORINFO CurInfo;
     HBITMAP bmpMask, bmpColor, bmpAlpha;
@@ -261,8 +276,18 @@ IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
     {
         /* This object doesn't belong to this process */
         EngSetLastError(ERROR_INVALID_HANDLE);
+        /* Caller expects us to dereference! */
+        UserDereferenceObject(CurIcon);
         return FALSE;
     }
+    
+    /* We found our process, but we're told to not destroy it in case it is shared */
+    if((CurIcon->ustrModule.Buffer != NULL) && !bForce)
+    {
+        /* Tests show this is a valid call */
+        UserDereferenceObject(CurIcon);
+        return TRUE;
+    }
 
     ExFreeToPagedLookasideList(pgProcessLookasideList, Current);
 
@@ -314,6 +339,11 @@ emptyList:
         GreDeleteObject(bmpAlpha);
         CurIcon->aFrame[0].hbmAlpha = NULL;
     }
+    
+    if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer))
+        ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING);
+    if(CurIcon->ustrModule.Buffer)
+        ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode);
 
     /* We were given a pointer, no need to keep the reference anylonger! */
     UserDereferenceObject(CurIcon);
@@ -331,7 +361,7 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
     LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
     {
         UserReferenceObject(CurIcon);
-        IntDestroyCurIconObject(CurIcon, Win32Process);
+        IntDestroyCurIconObject(CurIcon, Win32Process, TRUE);
     }
 }
 
@@ -342,12 +372,12 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
 BOOL
 APIENTRY
 NtUserGetIconInfo(
-    HANDLE hCurIcon,
-    PICONINFO IconInfo,
-    PUNICODE_STRING lpInstName, // Optional
-    PUNICODE_STRING lpResName,  // Optional
-    LPDWORD pbpp,               // Optional
-    BOOL bInternal)
+  _In_       HANDLE hCurIcon,
+  _Out_opt_  PICONINFO IconInfo,
+  _Out_opt_  PUNICODE_STRING lpModule,   // Optional
+  _Out_opt_  PUNICODE_STRING lpResName,  // Optional
+  _Out_opt_  LPDWORD pbpp,               // Optional
+  _In_       BOOL bInternal)
 {
     ICONINFO ii;
     PCURICON_OBJECT CurIcon;
@@ -356,66 +386,145 @@ NtUserGetIconInfo(
     DWORD colorBpp = 0;
 
     TRACE("Enter NtUserGetIconInfo\n");
-    UserEnterExclusive();
 
-    if (!IconInfo)
+    /* Check if something was actually asked */
+    if (!IconInfo && !lpModule && !lpResName)
     {
+        WARN("Nothing to fill.\n");
         EngSetLastError(ERROR_INVALID_PARAMETER);
-        goto leave;
+        return FALSE;
     }
+    
+    UserEnterExclusive();
 
     if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
     {
-        goto leave;
+        WARN("UserGetIconObject(0x%08x) Failed.\n", hCurIcon);
+        UserLeave();
+        return FALSE;
     }
     
-    /* Fill data */
-    ii.fIcon = CurIcon->bIcon;
-    ii.xHotspot = CurIcon->ptlHotspot.x;
-    ii.yHotspot = CurIcon->ptlHotspot.y;
+    /* Give back the icon information */
+    if(IconInfo)
+    {
+        /* Fill data */
+        ii.fIcon = CurIcon->bIcon;
+        ii.xHotspot = CurIcon->ptlHotspot.x;
+        ii.yHotspot = CurIcon->ptlHotspot.y;
 
-    /* Copy bitmaps */
-    ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask);
-    ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor);
+        /* Copy bitmaps */
+        ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask);
+        GreSetObjectOwner(ii.hbmMask, GDI_OBJ_HMGR_POWNED);
+        ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor);
+        GreSetObjectOwner(ii.hbmColor, GDI_OBJ_HMGR_POWNED);
 
-    if (pbpp)
-    {
-        PSURFACE psurfBmp;
+        if (pbpp)
+        {
+            PSURFACE psurfBmp;
 
-        psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
-        if (psurfBmp)
+            psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
+            if (psurfBmp)
+            {
+                colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
+                SURFACE_ShareUnlockSurface(psurfBmp);
+            }
+        }
+
+        /* Copy fields */
+        _SEH2_TRY
         {
-            colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
-            SURFACE_ShareUnlockSurface(psurfBmp);
+            ProbeForWrite(IconInfo, sizeof(ICONINFO), 1);
+            RtlCopyMemory(IconInfo, &ii, sizeof(ICONINFO));
+
+            if (pbpp)
+            {
+                ProbeForWrite(pbpp, sizeof(DWORD), 1);
+                *pbpp = colorBpp;
+            }
         }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END
     }
 
-    /* Copy fields */
-    _SEH2_TRY
+    if (!NT_SUCCESS(Status))
     {
-        ProbeForWrite(IconInfo, sizeof(ICONINFO), 1);
-        RtlCopyMemory(IconInfo, &ii, sizeof(ICONINFO));
+        WARN("Status: 0x%08x.\n", Status);
+        SetLastNtError(Status);
+        goto leave;
+    }
 
-        if (pbpp)
+    /* Give back the module name */
+    if(lpModule)
+    {
+        if(!CurIcon->ustrModule.Buffer)
         {
-            ProbeForWrite(pbpp, sizeof(DWORD), 1);
-            *pbpp = colorBpp;
+            EngSetLastError(ERROR_INVALID_HANDLE);
+            goto leave;
         }
+        /* Copy what we can */
+        _SEH2_TRY
+        {
+            ProbeForWrite(lpModule, sizeof(UNICODE_STRING), 1);
+            ProbeForWrite(lpModule->Buffer, lpModule->MaximumLength, 1);
+            lpModule->Length = min(lpModule->MaximumLength, CurIcon->ustrModule.Length);
+            RtlCopyMemory(lpModule->Buffer, CurIcon->ustrModule.Buffer, lpModule->Length);
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END
     }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+
+    if (!NT_SUCCESS(Status))
     {
-        Status = _SEH2_GetExceptionCode();
+        SetLastNtError(Status);
+        goto leave;
+    }
+    
+    if(lpResName)
+    {
+        if(!CurIcon->ustrRsrc.Buffer)
+        {
+            EngSetLastError(ERROR_INVALID_HANDLE);
+            goto leave;
+        }
+        /* Copy it */
+        _SEH2_TRY
+        {
+            ProbeForWrite(lpResName, sizeof(UNICODE_STRING), 1);
+            if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer))
+            {
+                lpResName->Buffer = CurIcon->ustrRsrc.Buffer;
+                lpResName->Length = 0;
+            }
+            else
+            {
+                lpResName->Length = min(lpResName->MaximumLength, CurIcon->ustrRsrc.Length);
+                RtlCopyMemory(lpResName->Buffer, CurIcon->ustrRsrc.Buffer, lpResName->Length);
+            }
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END
     }
-    _SEH2_END
 
-    if (NT_SUCCESS(Status))
-        Ret = TRUE;
-    else
+    if (!NT_SUCCESS(Status))
+    {
         SetLastNtError(Status);
+        goto leave;
+    }
+    
+    Ret = TRUE;
 
+leave:
     UserDereferenceObject(CurIcon);
 
-leave:
     TRACE("Leave NtUserGetIconInfo, ret=%i\n", Ret);
     UserLeave();
 
@@ -623,8 +732,8 @@ NtUserClipCursor(
 BOOL
 APIENTRY
 NtUserDestroyCursor(
-    HANDLE hCurIcon,
-    DWORD Unknown)
+  _In_   HANDLE hCurIcon,
+  _In_   BOOL bForce)
 {
     PCURICON_OBJECT CurIcon;
     BOOL ret;
@@ -638,7 +747,7 @@ NtUserDestroyCursor(
         RETURN(FALSE);
     }
 
-    ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
+    ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process(), bForce);
     /* Note: IntDestroyCurIconObject will remove our reference for us! */
 
     RETURN(ret);
@@ -654,36 +763,51 @@ CLEANUP:
  * @implemented
  */
 HICON
-APIENTRY
+NTAPI
 NtUserFindExistingCursorIcon(
-    HMODULE hModule,
-    HRSRC hRsrc,
-    LONG cx,
-    LONG cy)
+  _In_  PUNICODE_STRING pustrModule,
+  _In_  PUNICODE_STRING pustrRsrc,
+  _In_  FINDEXISTINGCURICONPARAM* param)
 {
     PCURICON_OBJECT CurIcon;
-    HANDLE Ret = (HANDLE)0;
-    DECLARE_RETURN(HICON);
+    HICON Ret = NULL;
+    UNICODE_STRING ustrModuleSafe, ustrRsrcSafe;
+    FINDEXISTINGCURICONPARAM paramSafe;
+    NTSTATUS Status;
 
     TRACE("Enter NtUserFindExistingCursorIcon\n");
-    UserEnterExclusive();
-
-    CurIcon = IntFindExistingCurIconObject(hModule, hRsrc, cx, cy);
-    if (CurIcon)
+    
+    /* Capture resource name (it can be an INTRESOURCE == ATOM) */
+    Status = ProbeAndCaptureUnicodeStringOrAtom(&ustrRsrcSafe, pustrRsrc);
+    if(!NT_SUCCESS(Status))
+        return NULL;
+    Status = ProbeAndCaptureUnicodeString(&ustrModuleSafe, UserMode, pustrModule);
+    if(!NT_SUCCESS(Status))
+        goto done;
+    
+    _SEH2_TRY
     {
-        Ret = CurIcon->Self;
-
-//      IntReleaseCurIconObject(CurIcon); // FIXME: Is this correct? Does IntFindExistingCurIconObject add a ref?
-        RETURN(Ret);
+        ProbeForRead(param, sizeof(*param), 1);
+        paramSafe = *param;
     }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END
 
-    EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
-    RETURN((HANDLE)0);
-
-CLEANUP:
-    TRACE("Leave NtUserFindExistingCursorIcon, ret=%p\n",_ret_);
+    UserEnterExclusive();
+    CurIcon = IntFindExistingCurIconObject(&ustrModuleSafe, &ustrRsrcSafe, &paramSafe);
+    if (CurIcon)
+        Ret = CurIcon->Self;
     UserLeave();
-    END_CLEANUP;
+
+done:
+    if(!IS_INTRESOURCE(ustrRsrcSafe.Buffer))
+        ExFreePoolWithTag(ustrRsrcSafe.Buffer, TAG_STRING);
+    ReleaseCapturedUnicodeString(&ustrModuleSafe, UserMode);
+    
+    return Ret;
 }
 
 
@@ -920,12 +1044,6 @@ NtUserSetCursorContents(
 
 done:
 
-    if(!Ret)
-    {
-        IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
-        CurIcon = NULL;
-    }
-
     if (CurIcon)
     {
         UserDereferenceObject(CurIcon);
@@ -942,33 +1060,35 @@ CLEANUP:
 /*
  * @implemented
  */
-#ifdef NEW_CURSORICON
 BOOL
 APIENTRY
 NtUserSetCursorIconData(
-  _In_ HCURSOR Handle,
-  _In_ HINSTANCE hinst,
-  _In_ HRSRC hrsrc,
-  _In_ PICONINFO pIconInfo)
+  _In_     HCURSOR Handle,
+  _In_opt_ PUNICODE_STRING pustrModule,
+  _In_opt_ PUNICODE_STRING pustrRsrc,
+  _In_     PICONINFO pIconInfo)
 {
     PCURICON_OBJECT CurIcon;
     PSURFACE psurfBmp;
     NTSTATUS Status = STATUS_SUCCESS;
     BOOL Ret = FALSE;
-    DECLARE_RETURN(BOOL);
     ICONINFO ii;
-
+    
     TRACE("Enter NtUserSetCursorIconData\n");
+    
+    /* If a module name is provided, we need a resource name, and vice versa */
+    if((pustrModule && !pustrRsrc) || (!pustrModule && pustrRsrc))
+        return FALSE;
+    
     UserEnterExclusive();
 
     if (!(CurIcon = UserGetCurIconObject(Handle)))
     {
-        RETURN(FALSE);
+        UserLeave();
+        EngSetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
     }
 
-    CurIcon->hModule = hinst;
-    CurIcon->hRsrc =hrsrc;
-
     _SEH2_TRY
     {
         ProbeForRead(pIconInfo, sizeof(ICONINFO), 1);
@@ -1014,29 +1134,38 @@ NtUserSetCursorIconData(
 
     if (CurIcon->aFrame[0].hbmColor)
     {
-        if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor)))
-        {
-            CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
-            CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
-            SURFACE_ShareUnlockSurface(psurfBmp);
-            GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
-        }
-        else
+        psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
+        if(!psurfBmp)
             goto done;
+
+        CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+        CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
+        SURFACE_ShareUnlockSurface(psurfBmp);
+        GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC);
     }
     else
     {
-       if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask)))
-        {
-            CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
-            CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2;
-            SURFACE_ShareUnlockSurface(psurfBmp);
-        }
-        else
+        psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask);
+        if(!psurfBmp)
             goto done;
+
+        CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+        CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2;
+        SURFACE_ShareUnlockSurface(psurfBmp);
     }
     GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
     
+    if(pustrModule)
+    {
+        /* We use this convenient function, because INTRESOURCEs and ATOMs are the same */
+        Status = ProbeAndCaptureUnicodeStringOrAtom(&CurIcon->ustrRsrc, pustrRsrc);
+        if(!NT_SUCCESS(Status))
+            goto done;
+        Status = ProbeAndCaptureUnicodeString(&CurIcon->ustrModule, UserMode, pustrModule);
+        if(!NT_SUCCESS(Status))
+            goto done;
+    }
+    
     Ret = TRUE;
 
 done:
@@ -1055,97 +1184,17 @@ done:
             GreDeleteObject(CurIcon->aFrame[0].hbmColor);
             CurIcon->aFrame[0].hbmColor = NULL;
         }
-    }
-    RETURN(Ret);
-
-CLEANUP:
-    TRACE("Leave NtUserSetCursorIconData, ret=%i\n",_ret_);
-    UserLeave();
-    END_CLEANUP;
-}
-#else
-BOOL
-APIENTRY
-NtUserSetCursorIconData(
-    HANDLE hCurIcon,
-    PBOOL fIcon,
-    POINT *Hotspot,
-    HMODULE hModule,
-    HRSRC hRsrc,
-    HRSRC hGroupRsrc)
-{
-    PCURICON_OBJECT CurIcon;
-    NTSTATUS Status;
-    BOOL Ret = FALSE;
-    DECLARE_RETURN(BOOL);
-
-    TRACE("Enter NtUserSetCursorIconData\n");
-    UserEnterExclusive();
-
-    if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
-    {
-        RETURN(FALSE);
-    }
-
-    CurIcon->hModule = hModule;
-    CurIcon->hRsrc = hRsrc;
-    CurIcon->hGroupRsrc = hGroupRsrc;
-
-    /* Copy fields */
-    if (fIcon)
-    {
-        Status = MmCopyFromCaller(&CurIcon->bIcon, fIcon, sizeof(BOOL));
-        if (!NT_SUCCESS(Status))
-        {
-            SetLastNtError(Status);
-            goto done;
-        }
-    }
-    else
-    {
-        if (!Hotspot)
-            Ret = TRUE;
+        if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer))
+            ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING);
+        if(CurIcon->ustrModule.Buffer)
+            ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode);
     }
 
-    if (Hotspot)
-    {
-        Status = MmCopyFromCaller(&CurIcon->ptlHotspot, Hotspot, sizeof(POINT));
-        if (!NT_SUCCESS(Status))
-        {
-            SetLastNtError(Status);
-            goto done;
-        }
-    }
-
-    if (!fIcon && !Hotspot)
-    {
-        Ret = TRUE;
-    }
-
-done:
-       if(Ret)
-       {
-               /* This icon is shared now */
-               GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
-               if(CurIcon->aFrame[0].hbmColor)
-               {
-                       GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC);
-               }
-               if(CurIcon->aFrame[0].hbmAlpha)
-               {
-                       GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
-               }
-       }
-    UserDereferenceObject(CurIcon);
-    RETURN(Ret);
-
-
-CLEANUP:
-    TRACE("Leave NtUserSetCursorIconData, ret=%i\n",_ret_);
+    TRACE("Leave NtUserSetCursorIconData, ret=%i\n",Ret);
     UserLeave();
-    END_CLEANUP;
+    
+    return Ret;
 }
-#endif
 
 /* Mostly inspired from wine code.
  * We use low level functions because:
@@ -1167,7 +1216,7 @@ UserDrawIconEx(
     HBRUSH hbrFlickerFreeDraw,
     UINT diFlags)
 {
-    PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen;
+    PSURFACE psurfDest, psurfMask, psurfColor; //, psurfOffScreen = NULL;
     PDC pdc = NULL;
     BOOL Ret = FALSE;
     HBITMAP hbmMask, hbmColor, hbmAlpha;
@@ -1215,6 +1264,35 @@ UserDrawIconEx(
         return FALSE;
     }
     
+    pdc = DC_LockDc(hDc);
+    if(!pdc)
+    {
+        ERR("Could not lock the destination DC.\n");
+        SURFACE_ShareUnlockSurface(psurfMask);
+        if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
+        return FALSE;
+    }
+    /* Calculate destination rectangle */
+    RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
+    IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
+    RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
+    
+    /* Prepare the underlying surface */
+    DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
+
+    /* We now have our destination surface and rectangle */
+    psurfDest = pdc->dclevel.pSurface;
+    
+    if(psurfDest == NULL)
+    {
+        /* Empty DC */
+        DC_vFinishBlit(pdc, NULL);
+        DC_UnlockDc(pdc);
+        SURFACE_ShareUnlockSurface(psurfMask);
+        if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
+        return FALSE;
+    }
+    
     /* Set source rect */
     RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy);
 
@@ -1239,7 +1317,8 @@ UserDrawIconEx(
     }
 
     /* Should we render off-screen? */
-    bOffScreen = hbrFlickerFreeDraw && (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH);
+    bOffScreen = hbrFlickerFreeDraw && 
+        (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH);
 
     if (bOffScreen)
     {
@@ -1252,21 +1331,18 @@ UserDrawIconEx(
         if(!pbrush)
         {
             ERR("Failed to get brush object.\n");
-            SURFACE_ShareUnlockSurface(psurfMask);
-            if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
-            return FALSE;
+            goto Cleanup;
         }
 
+#if 0 //We lock the hdc surface during the whole function it makes no sense to use an offscreen surface for "flicker free" drawing
         psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP,
-            cxWidth, cyHeight, psurfColor->SurfObj.iBitmapFormat,
+            cxWidth, cyHeight, psurfDest->SurfObj.iBitmapFormat,
             0, 0, NULL);
         if(!psurfOffScreen)
         {
             ERR("Failed to allocate the off-screen surface.\n");
-            SURFACE_ShareUnlockSurface(psurfMask);
-            if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
             BRUSH_ShareUnlockBrush(pbrush);
-            return FALSE;
+            goto Cleanup;
         }
         
         /* Paint the brush */
@@ -1292,52 +1368,45 @@ UserDrawIconEx(
         if(!Ret)
         {
             ERR("Failed to paint the off-screen surface.\n");
-            SURFACE_ShareUnlockSurface(psurfMask);
-            if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
-            GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
-            return FALSE;
+            goto Cleanup;
         }
         
         /* We now have our destination surface */
         psurfDest = psurfOffScreen;
+#else
+        pdcClipObj = pdc->rosdc.CombinedClip;
+        /* Paint the brush */
+        EBRUSHOBJ_vInit(&eboFill, pbrush, psurfDest, 0x00FFFFFF, 0, NULL);
+        
+        Ret = IntEngBitBlt(&psurfDest->SurfObj,
+            NULL,
+            NULL,
+            pdcClipObj,
+            NULL,
+            &rcDest,
+            NULL,
+            NULL,
+            &eboFill.BrushObject,
+            &pbrush->ptOrigin,
+            ROP4_PATCOPY);
+
+        /* Clean up everything */
+        EBRUSHOBJ_vCleanup(&eboFill);
+        BRUSH_ShareUnlockBrush(pbrush);
+            
+        if(!Ret)
+        {
+            ERR("Failed to paint the off-screen surface.\n");
+            goto Cleanup;
+        }
+#endif
     }
     else
     {
         /* We directly draw to the DC */
         TRACE("Performing on screen rendering.\n");
-        
-        psurfOffScreen = NULL;
-        pdc = DC_LockDc(hDc);
-        if(!pdc)
-        {
-            ERR("Could not lock the destination DC.\n");
-            SURFACE_ShareUnlockSurface(psurfMask);
-            if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
-            return FALSE;
-        }
-        /* Calculate destination rectangle */
-        RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
-        IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
-        RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
-        
-        /* Prepare the underlying surface */
-        DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
-        
-        /* Get the clip object */
         pdcClipObj = pdc->rosdc.CombinedClip;
-        
-        /* We now have our destination surface and rectangle */
-        psurfDest = pdc->dclevel.pSurface;
-        
-        if(psurfDest == NULL)
-        {
-            /* Empty DC */
-            DC_vFinishBlit(pdc, NULL);
-            DC_UnlockDc(pdc);
-            SURFACE_ShareUnlockSurface(psurfMask);
-            if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
-            return FALSE;
-        }
+        // psurfOffScreen = NULL;
     }
 
     /* Now do the rendering */
@@ -1460,36 +1529,23 @@ NoAlpha:
     }
 
 done:
+#if 0
     /* We're done. Was it a double buffered draw ? */
     if(bOffScreen)
     {
         /* Yes. Draw it back to our DC */
         POINTL ptSrc = {0, 0};
-        pdc = DC_LockDc(hDc);
-        if(!pdc)
-        {
-            ERR("Could not lock the destination DC.\n");
-            return FALSE;
-        }
+
         /* Calculate destination rectangle */
         RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
         IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
         RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
         
-        /* Prepare the underlying surface */
-        DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
-        
         /* Get the clip object */
         pdcClipObj = pdc->rosdc.CombinedClip;
         
         /* We now have our destination surface and rectangle */
         psurfDest = pdc->dclevel.pSurface;
-        if(!psurfDest)
-        {
-            /* So, you did all of this for an empty DC. */
-            DC_UnlockDc(pdc);
-            goto Cleanup2;
-        }
         
         /* Color translation */
         EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
@@ -1509,18 +1565,20 @@ done:
                            
         EXLATEOBJ_vCleanup(&exlo);
     }
+#endif
 Cleanup:
     if(pdc)
     {
         DC_vFinishBlit(pdc, NULL);
         DC_UnlockDc(pdc);
     }
-    
-Cleanup2:
+
+#if 0
     /* Delete off screen rendering surface */
     if(psurfOffScreen)
         GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
-    
+#endif
+
     /* Unlock other surfaces */
     SURFACE_ShareUnlockSurface(psurfMask);
     if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
@@ -1554,7 +1612,7 @@ NtUserDrawIconEx(
 
     if (!(pIcon = UserGetCurIconObject(hIcon)))
     {
-        ERR("UserGetCurIconObject() failed!\n");
+        ERR("UserGetCurIconObject(0x%08x) failed!\n", hIcon);
         UserLeave();
         return FALSE;
     }
index cc0e6a9..3b65d98 100644 (file)
@@ -236,7 +236,7 @@ NtUserCallOneParam(
             PCURICON_OBJECT CurIcon;
                        DWORD_PTR Result ;
 
-            if (!(CurIcon = IntCreateCurIconHandle()))
+            if (!(CurIcon = IntCreateCurIconHandle((DWORD)Param)))
             {
                EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
                RETURN(0);
index 8c5930d..d7bfe86 100644 (file)
@@ -71,7 +71,10 @@ else()
 endif()
 
 add_library(user32 SHARED ${SOURCE})
-set_module_type(user32 win32dll UNICODE)
+set_module_type(user32
+    win32dll
+    ENTRYPOINT DllMain 12
+    UNICODE)
 
 target_link_libraries(user32
     user32_wsprintf
@@ -79,8 +82,13 @@ target_link_libraries(user32
     win32ksys
     ${PSEH_LIB})
 
+if(MSVC)
+    # for __ftol2_sse, float to int cast helper
+    target_link_libraries(user32 msvcrtex)
+endif()
+
 add_delay_importlibs(user32 imm32 usp10)
-add_importlibs(user32 gdi32 advapi32 msvcrt kernel32 ntdll)
+add_importlibs(user32 gdi32 advapi32 kernel32 ntdll)
 add_pch(user32 include/user32.h)
 add_cd_file(TARGET user32 DESTINATION reactos/system32 FOR all)
 
index 511f049..a70c4fd 100644 (file)
@@ -400,7 +400,7 @@ static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData_linedef(EDITSTATE *es, HD
                tabdef.pTabStops = es->tabs;
                tabdef.iTabOrigin = 0;
 
-               ScriptStringAnalyse(udc, &es->text[index], line_def->net_length, (1.5*line_def->net_length+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS|SSA_TAB, -1, NULL, NULL, NULL, &tabdef, NULL, &line_def->ssa);
+               ScriptStringAnalyse(udc, &es->text[index], line_def->net_length, (3*line_def->net_length/2+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS|SSA_TAB, -1, NULL, NULL, NULL, &tabdef, NULL, &line_def->ssa);
 
                if (es->font)
                        SelectObject(udc, old_font);
@@ -435,9 +435,9 @@ static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData(EDITSTATE *es, HDC dc, IN
                                old_font = SelectObject(udc, es->font);
 
                        if (es->style & ES_PASSWORD)
-                               ScriptStringAnalyse(udc, &es->password_char, length, (1.5*length+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS|SSA_PASSWORD, -1, NULL, NULL, NULL, NULL, NULL, &es->ssa);
+                               ScriptStringAnalyse(udc, &es->password_char, length, (3*length/2+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS|SSA_PASSWORD, -1, NULL, NULL, NULL, NULL, NULL, &es->ssa);
                        else
-                               ScriptStringAnalyse(udc, es->text, length, (1.5*length+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS, -1, NULL, NULL, NULL, NULL, NULL, &es->ssa);
+                               ScriptStringAnalyse(udc, es->text, length, (3*length/2+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS, -1, NULL, NULL, NULL, NULL, NULL, &es->ssa);
 
                        if (es->font)
                                SelectObject(udc, old_font);
index d127619..3635dbc 100644 (file)
@@ -11,7 +11,7 @@
 #include <wine/debug.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(cursor);
-//WINE_DECLARE_DEBUG_CHANNEL(icon);
+WINE_DECLARE_DEBUG_CHANNEL(icon);
 //WINE_DECLARE_DEBUG_CHANNEL(resource);
 
 /************* USER32 INTERNAL FUNCTIONS **********/
@@ -55,6 +55,30 @@ HCURSOR CursorIconToCursor(HICON hIcon, BOOL SemiTransparent)
 
 /************* IMPLEMENTATION HELPERS ******************/
 
+static const WCHAR DISPLAYW[] = L"DISPLAY";
+
+static void *map_fileW( LPCWSTR name, LPDWORD filesize )
+{
+    HANDLE hFile, hMapping;
+    LPVOID ptr = NULL;
+
+    hFile = CreateFileW( name, GENERIC_READ, FILE_SHARE_READ, NULL,
+                         OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0 );
+    if (hFile != INVALID_HANDLE_VALUE)
+    {
+        hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
+        if (hMapping)
+        {
+            ptr = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
+            CloseHandle( hMapping );
+            if (filesize)
+                *filesize = GetFileSize( hFile, NULL );
+        }
+        CloseHandle( hFile );
+    }
+    return ptr;
+}
+
 static int get_dib_image_size( int width, int height, int depth )
 {
     return (((width * depth + 31) / 8) & ~3) * abs( height );
@@ -121,6 +145,32 @@ static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
     }
 }
 
+static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
+                              LONG *height, WORD *bpp, DWORD *compr )
+{
+    if (header->biSize == sizeof(BITMAPCOREHEADER))
+    {
+        const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
+        *width  = core->bcWidth;
+        *height = core->bcHeight;
+        *bpp    = core->bcBitCount;
+        *compr  = 0;
+        return 0;
+    }
+    else if (header->biSize == sizeof(BITMAPINFOHEADER) ||
+             header->biSize == sizeof(BITMAPV4HEADER) ||
+             header->biSize == sizeof(BITMAPV5HEADER))
+    {
+        *width  = header->biWidth;
+        *height = header->biHeight;
+        *bpp    = header->biBitCount;
+        *compr  = header->biCompression;
+        return 1;
+    }
+    ERR("(%d): unknown/wrong size for header\n", header->biSize );
+    return -1;
+}
+
 /************* IMPLEMENTATION CORE ****************/
 
 static BOOL CURSORICON_GetIconInfoFromBMI(
@@ -132,28 +182,35 @@ static BOOL CURSORICON_GetIconInfoFromBMI(
 {
     UINT ubmiSize = bitmap_info_size(pbmi, DIB_RGB_COLORS);
     BOOL monochrome = is_dib_monochrome(pbmi);
+    LONG width, height;
+    WORD bpp;
+    DWORD compr;
+    int ibmpType;
     HDC hdc, hdcScreen;
     BITMAPINFO* pbmiCopy;
     HBITMAP hbmpOld = NULL;
     BOOL bResult = FALSE;
     const VOID *pvColor, *pvMask;
     
-    /* Check for invalid data */
-    if ( (pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER) &&
-          pbmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER))  ||
-        pbmi->bmiHeader.biCompression != BI_RGB )
-    {
-          WARN("Invalid resource bitmap header.\n");
-          return FALSE;
-    }
+    ibmpType = DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr);
+    /* Invalid data */
+    if(ibmpType < 0)
+        return FALSE;
+    
+    /* No compression for icons */
+    if(compr != BI_RGB)
+        return FALSE;
     
     /* Fix the hotspot coords */
-    if(cxDesired != pbmi->bmiHeader.biWidth)
-        pii->xHotspot = (pii->xHotspot * cxDesired) / pbmi->bmiHeader.biWidth;
-    if(cxDesired != (pbmi->bmiHeader.biHeight/2))
-        pii->yHotspot = (pii->yHotspot * cyDesired * 2) / pbmi->bmiHeader.biHeight;
+    if(!pii->fIcon)
+    {
+        if(cxDesired != pbmi->bmiHeader.biWidth)
+            pii->xHotspot = (pii->xHotspot * cxDesired) / pbmi->bmiHeader.biWidth;
+        if(cxDesired != (pbmi->bmiHeader.biHeight/2))
+            pii->yHotspot = (pii->yHotspot * cyDesired * 2) / pbmi->bmiHeader.biHeight;
+    }
     
-    hdcScreen = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
+    hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
     if(!hdcScreen)
         return FALSE;
     hdc = CreateCompatibleDC(hdcScreen);
@@ -167,8 +224,13 @@ static BOOL CURSORICON_GetIconInfoFromBMI(
     if(!pbmiCopy)
         goto done;
     RtlCopyMemory(pbmiCopy, pbmi, ubmiSize);
-    pbmiCopy->bmiHeader.biHeight /= 2;
     
+    /* In an icon/cursor, the BITMAPINFO holds twice the height */
+    if(pbmiCopy->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+        ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcHeight /= 2;
+    else
+        pbmiCopy->bmiHeader.biHeight /= 2;
+        
     pvColor = (const char*)pbmi + ubmiSize;
     pvMask = (const char*)pvColor +
         get_dib_image_size(pbmi->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, pbmi->bmiHeader.biBitCount );
@@ -250,7 +312,7 @@ done:
 }
 
 static
-HANDLE
+HBITMAP
 BITMAP_LoadImageW(
   _In_opt_  HINSTANCE hinst,
   _In_      LPCWSTR lpszName,
@@ -259,8 +321,400 @@ BITMAP_LoadImageW(
   _In_      UINT fuLoad
 )
 {
-    UNIMPLEMENTED;
-    return NULL;
+    const BITMAPINFO* pbmi;
+    BITMAPINFO* pbmiScaled = NULL;
+    BITMAPINFO* pbmiCopy = NULL;
+    const VOID* pvMapping;
+    DWORD dwOffset = 0;
+    HGLOBAL hgRsrc;
+    int iBMISize;
+    PVOID pvBits;
+    HDC hdcScreen = NULL;
+    HDC hdc = NULL;
+    HBITMAP hbmpRet, hbmpOld;
+
+    /* Map the bitmap info */
+    if(fuLoad & LR_LOADFROMFILE)
+    {
+        const BITMAPFILEHEADER* pbmfh;
+        
+        pvMapping = map_fileW(lpszName, NULL);
+        if(!pvMapping)
+            return NULL;
+        pbmfh = pvMapping;
+        if (pbmfh->bfType != 0x4d42 /* 'BM' */)
+        {
+            WARN("Invalid/unsupported bitmap format!\n");
+            goto end;
+        }
+        pbmi = (const BITMAPINFO*)(pbmfh + 1);
+        
+        /* Get the image bits */
+        if(pbmfh->bfOffBits)
+            dwOffset = pbmfh->bfOffBits - sizeof(BITMAPFILEHEADER);
+    }
+    else
+    {
+        HRSRC hrsrc;
+        
+        /* Caller wants an OEM bitmap */
+        if(!hinst)
+            hinst = User32Instance;
+        hrsrc = FindResourceW(hinst, lpszName, (LPWSTR)RT_BITMAP);
+        if(!hrsrc)
+            return NULL;
+        hgRsrc = LoadResource(hinst, hrsrc);
+        if(!hgRsrc)
+            return NULL;
+        pbmi = LockResource(hgRsrc);
+        if(!pbmi)
+            return NULL;
+    }
+    
+    /* See if we must scale the bitmap */
+    iBMISize = bitmap_info_size(pbmi, DIB_RGB_COLORS);
+    
+    /* Get a pointer to the image data */
+    pvBits = (char*)pbmi + (dwOffset ? dwOffset : iBMISize);
+
+    /* Create a copy of the info describing the bitmap in the file */
+    pbmiCopy = HeapAlloc(GetProcessHeap(), 0, iBMISize);
+    if(!pbmiCopy)
+        goto end;
+    CopyMemory(pbmiCopy, pbmi, iBMISize);
+    
+    /* Fix it up, if needed */
+    if(fuLoad & (LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS))
+    {
+        WORD bpp, incr, numColors;
+        char* pbmiColors;
+        RGBTRIPLE* ptr;
+        COLORREF crWindow, cr3DShadow, cr3DFace, cr3DLight;
+        BYTE pixel = *((BYTE*)pvBits);
+        UINT i;
+        
+        if(pbmiCopy->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+        {
+            bpp = ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount;
+            numColors = 1 << bpp;
+            /* BITMAPCOREINFO holds RGBTRIPLEs */
+            incr = 3;
+        }
+        else
+        {
+            bpp = pbmiCopy->bmiHeader.biBitCount;
+            /* BITMAPINFOHEADER holds RGBQUADs */
+            incr = 4;
+            numColors = pbmiCopy->bmiHeader.biClrUsed;
+            if(numColors > 256) numColors = 256;
+            if (!numColors && (bpp <= 8)) numColors = 1 << bpp;
+        }
+        
+        if(bpp > 8)
+            goto create_bitmap;
+
+        pbmiColors = (char*)pbmiCopy + pbmiCopy->bmiHeader.biSize;
+        
+        /* Get the relevant colors */
+        crWindow = GetSysColor(COLOR_WINDOW);
+        cr3DShadow = GetSysColor(COLOR_3DSHADOW);
+        cr3DFace = GetSysColor(COLOR_3DFACE);
+        cr3DLight = GetSysColor(COLOR_3DLIGHT);
+        
+        /* Fix the transparent palette entry */
+        if(fuLoad & LR_LOADTRANSPARENT)
+        {
+            switch(bpp)
+            {
+                case 1: pixel >>= 7; break;
+                case 4: pixel >>= 4; break;
+                case 8: break;
+                default:
+                    FIXME("Unhandled bit depth %d.\n", bpp);
+                    goto create_bitmap;
+            }
+            
+            if(pixel >= numColors)
+            {
+                ERR("Wrong pixel passed in.\n");
+                goto create_bitmap;
+            }
+            
+            /* If both flags are set, we must use COLOR_3DFACE */
+            if(fuLoad & LR_LOADMAP3DCOLORS) crWindow = cr3DFace;
+            
+            /* Define the color */
+            ptr = (RGBTRIPLE*)(pbmiColors + pixel*incr);
+            ptr->rgbtBlue = GetBValue(crWindow);
+            ptr->rgbtGreen = GetGValue(crWindow);
+            ptr->rgbtRed = GetRValue(crWindow);
+            goto create_bitmap;
+        }
+        
+        /* If we are here, then LR_LOADMAP3DCOLORS is set without LR_TRANSPARENT */
+        for(i = 0; i<numColors; i++)
+        {
+            ptr = (RGBTRIPLE*)(pbmiColors + i*incr);
+            if((ptr->rgbtBlue == ptr->rgbtRed) && (ptr->rgbtBlue == ptr->rgbtGreen))
+            {
+                if(ptr->rgbtBlue == 128)
+                {
+                    ptr->rgbtBlue = GetBValue(cr3DShadow);
+                    ptr->rgbtGreen = GetGValue(cr3DShadow);
+                    ptr->rgbtRed = GetRValue(cr3DShadow);
+                }
+                if(ptr->rgbtBlue == 192)
+                {
+                    ptr->rgbtBlue = GetBValue(cr3DFace);
+                    ptr->rgbtGreen = GetGValue(cr3DFace);
+                    ptr->rgbtRed = GetRValue(cr3DFace);
+                }
+                if(ptr->rgbtBlue == 223)
+                {
+                    ptr->rgbtBlue = GetBValue(cr3DLight);
+                    ptr->rgbtGreen = GetGValue(cr3DLight);
+                    ptr->rgbtRed = GetRValue(cr3DLight);
+                }
+            }
+        }
+    }
+
+create_bitmap:
+    if(fuLoad & LR_CREATEDIBSECTION)
+    {
+        /* Allocate the BMI describing the new bitmap */
+        pbmiScaled = HeapAlloc(GetProcessHeap(), 0, iBMISize);
+        if(!pbmiScaled)
+            goto end;
+        CopyMemory(pbmiScaled, pbmiCopy, iBMISize);
+        
+        /* Fix it up */
+        if(pbmiScaled->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+        {
+            BITMAPCOREHEADER* pbmch = (BITMAPCOREHEADER*)&pbmiScaled->bmiHeader;
+            if(cxDesired == 0)
+                cxDesired = pbmch->bcWidth;
+            if(cyDesired == 0)
+                cyDesired == pbmch->bcHeight;
+            else if(pbmch->bcHeight < 0)
+                cyDesired = -cyDesired;
+
+            pbmch->bcWidth = cxDesired;
+            pbmch->bcHeight = cyDesired;
+        }
+        else
+        {
+            if ((pbmi->bmiHeader.biHeight > 65535) || (pbmi->bmiHeader.biWidth > 65535)) {
+                WARN("Broken BITMAPINFO!\n");
+                goto end;
+            }
+            
+            if(cxDesired == 0)
+                cxDesired = pbmi->bmiHeader.biWidth;
+            if(cyDesired == 0)
+                cyDesired = pbmi->bmiHeader.biHeight;
+            else if(pbmi->bmiHeader.biHeight < 0)
+                cyDesired = -cyDesired;
+
+            pbmiScaled->bmiHeader.biWidth = cxDesired;
+            pbmiScaled->bmiHeader.biHeight = cyDesired;
+            /* No compression for DIB sections */
+            if(fuLoad & LR_CREATEDIBSECTION)
+                pbmiScaled->bmiHeader.biCompression = BI_RGB;
+        }
+    }
+    
+    /* Top-down image */
+    if(cyDesired < 0) cyDesired = -cyDesired;
+    
+    /* We need a device context */
+    hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
+    if(!hdcScreen)
+        goto end;
+    hdc = CreateCompatibleDC(hdcScreen);
+    if(!hdc)
+        goto end;
+    
+    /* Now create the bitmap */
+    if(fuLoad & LR_CREATEDIBSECTION)
+        hbmpRet = CreateDIBSection(hdc, pbmiScaled, DIB_RGB_COLORS, NULL, 0, 0);
+    else
+    {
+        if(is_dib_monochrome(pbmiCopy) || (fuLoad & LR_MONOCHROME))
+            hbmpRet = CreateBitmap(cxDesired, cyDesired, 1, 1, NULL);
+        else
+            hbmpRet = CreateCompatibleBitmap(hdcScreen, cxDesired, cyDesired);
+    }
+    
+    if(!hbmpRet)
+        goto end;
+    
+    hbmpOld = SelectObject(hdc, hbmpRet);
+    if(!hbmpOld)
+        goto end;
+    if(!StretchDIBits(hdc, 0, 0, cxDesired, cyDesired,
+                           0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biWidth,
+                           pvBits, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
+    {
+        ERR("StretchDIBits failed!.\n");
+        SelectObject(hdc, hbmpOld);
+        DeleteObject(hbmpRet);
+        hbmpRet = NULL;
+        goto end;
+    }
+
+    SelectObject(hdc, hbmpOld);
+
+end:
+    if(hdcScreen)
+        DeleteDC(hdcScreen);
+    if(hdc)
+        DeleteDC(hdc);
+    if(pbmiScaled)
+        HeapFree(GetProcessHeap(), 0, pbmiScaled);
+    if(pbmiCopy)
+        HeapFree(GetProcessHeap(), 0, pbmiCopy);
+    if (fuLoad & LR_LOADFROMFILE)
+        UnmapViewOfFile( pvMapping );
+    else
+        FreeResource(hgRsrc);
+
+    return hbmpRet;
+}
+
+#include "pshpack1.h"
+
+typedef struct {
+    BYTE bWidth;
+    BYTE bHeight;
+    BYTE bColorCount;
+    BYTE bReserved;
+    WORD xHotspot;
+    WORD yHotspot;
+    DWORD dwDIBSize;
+    DWORD dwDIBOffset;
+} CURSORICONFILEDIRENTRY;
+
+typedef struct
+{
+    WORD                idReserved;
+    WORD                idType;
+    WORD                idCount;
+    CURSORICONFILEDIRENTRY  idEntries[1];
+} CURSORICONFILEDIR;
+
+#include "poppack.h"
+
+static
+HANDLE
+CURSORICON_LoadFromFileW(
+  _In_      LPCWSTR lpszName,
+  _In_      int cxDesired,
+  _In_      int cyDesired,
+  _In_      UINT fuLoad,
+  _In_      BOOL bIcon
+)
+{
+    CURSORICONDIR* fakeDir;
+    CURSORICONDIRENTRY* fakeEntry;
+    CURSORICONFILEDIRENTRY *entry;
+    CURSORICONFILEDIR *dir;
+    DWORD filesize = 0;
+    LPBYTE bits;
+    HANDLE hRet = NULL;
+    WORD i;
+    ICONINFO ii;
+
+    TRACE("loading %s\n", debugstr_w( lpszName ));
+
+    bits = map_fileW( lpszName, &filesize );
+    if (!bits)
+        return NULL;
+
+    /* Check for .ani. */
+    if (memcmp( bits, "RIFF", 4 ) == 0)
+    {
+        UNIMPLEMENTED;
+        goto end;
+    }
+
+    dir = (CURSORICONFILEDIR*) bits;
+    if ( filesize < sizeof(*dir) )
+        goto end;
+
+    if ( filesize < (sizeof(*dir) + sizeof(dir->idEntries[0])*(dir->idCount-1)) )
+        goto end;
+    
+    /* 
+     * Cute little hack:
+     * We allocate a buffer, fake it as if it was a pointer to a resource in a module,
+     * pass it to LookupIconIdFromDirectoryEx and get back the index we have to use
+     */
+    fakeDir = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(CURSORICONDIR, idEntries[dir->idCount]));
+    if(!fakeDir)
+        goto end;
+    fakeDir->idReserved = 0;
+    fakeDir->idType = dir->idType;
+    fakeDir->idCount = dir->idCount;
+    for(i = 0; i<dir->idCount; i++)
+    {
+        fakeEntry = &fakeDir->idEntries[i];
+        entry = &dir->idEntries[i];
+        /* Take this as an occasion to perform a size check */
+        if((entry->dwDIBOffset + entry->dwDIBSize) > filesize)
+            goto end;
+        /* File icon/cursors are not like resource ones */
+        if(bIcon)
+        {
+            fakeEntry->ResInfo.icon.bWidth = entry->bWidth;
+            fakeEntry->ResInfo.icon.bHeight = entry->bHeight;
+            fakeEntry->ResInfo.icon.bColorCount = 0;
+            fakeEntry->ResInfo.icon.bReserved = 0;
+        }
+        else
+        {
+            fakeEntry->ResInfo.cursor.wWidth = entry->bWidth;
+            fakeEntry->ResInfo.cursor.wHeight = entry->bHeight;
+        }
+        /* Let's assume there's always one plane */
+        fakeEntry->wPlanes = 1;
+        /* We must get the bitcount from the BITMAPINFOHEADER itself */
+        fakeEntry->wBitCount = ((BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset))->biBitCount;
+        fakeEntry->dwBytesInRes = entry->dwDIBSize;
+        fakeEntry->wResId = i + 1;
+    }
+    
+    /* Now call LookupIconIdFromResourceEx */
+    i = LookupIconIdFromDirectoryEx((PBYTE)fakeDir, bIcon, cxDesired, cyDesired, fuLoad & LR_MONOCHROME);
+    /* We don't need this anymore */
+    HeapFree(GetProcessHeap(), 0, fakeDir);
+    if(i == 0)
+    {
+        WARN("Unable to get a fit entry index.\n");
+        goto end;
+    }
+    
+    /* Get our entry */
+    entry = &dir->idEntries[i-1];
+    /* A bit of preparation */
+    ii.xHotspot = entry->xHotspot;
+    ii.yHotspot = entry->yHotspot;
+    ii.fIcon = bIcon;
+    
+    /* Do the dance */
+    if(!CURSORICON_GetIconInfoFromBMI(&ii, (BITMAPINFO*)&bits[entry->dwDIBOffset], cxDesired, cyDesired))
+        goto end;
+    
+    /* Create the icon. NOTE: there's no LR_SHARED icons if they are created from file */
+    hRet = CreateIconIndirect(&ii);
+    
+    /* Clean up */
+    DeleteObject(ii.hbmMask);
+    DeleteObject(ii.hbmColor);
+    
+end:
+    UnmapViewOfFile(bits);
+    return hRet;
 }
 
 static
@@ -274,24 +728,83 @@ CURSORICON_LoadImageW(
   _In_      BOOL bIcon
 )
 {
-    HRSRC hrsrc, hrsrc2;
-    HANDLE handle, hCurIcon;
+    HRSRC hrsrc;
+    HANDLE handle, hCurIcon = NULL;
     CURSORICONDIR* dir;
     WORD wResId;
     LPBYTE bits;
     ICONINFO ii;
     BOOL bStatus;
+    UNICODE_STRING ustrRsrc;
+    UNICODE_STRING ustrModule = {0, 0, NULL};
+    
+    /* Fix width/height */
+    if(fuLoad & LR_DEFAULTSIZE)
+    {
+        if(!cxDesired) cxDesired = GetSystemMetrics(bIcon ? SM_CXICON : SM_CXCURSOR);
+        if(!cyDesired) cyDesired = GetSystemMetrics(bIcon ? SM_CYICON : SM_CYCURSOR);
+    }
     
     if(fuLoad & LR_LOADFROMFILE)
     {
-        UNIMPLEMENTED;
-        return NULL;
+        return CURSORICON_LoadFromFileW(lpszName, cxDesired, cyDesired, fuLoad, bIcon);
     }
     
     /* Check if caller wants OEM icons */
     if(!hinst)
         hinst = User32Instance;
     
+    if(fuLoad & LR_SHARED)
+    {
+        DWORD size = MAX_PATH;
+        FINDEXISTINGCURICONPARAM param;
+        
+        TRACE("Checking for an LR_SHARED cursor/icon.\n");
+        /* Prepare the resource name string */
+        if(IS_INTRESOURCE(lpszName))
+        {
+            ustrRsrc.Buffer = (LPWSTR)lpszName;
+            ustrRsrc.Length = 0;
+            ustrRsrc.MaximumLength = 0;
+        }
+        else
+            RtlInitUnicodeString(&ustrRsrc, lpszName);
+        
+        /* Prepare the module name string */
+        ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, size*sizeof(WCHAR));
+        /* Get it */
+        do
+        {
+            DWORD ret = GetModuleFileName(hinst, ustrModule.Buffer, size);
+            if(ret == 0)
+            {
+                HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
+                return NULL;
+            }
+            if(ret < size)
+            {
+                ustrModule.Length = ret;
+                ustrModule.MaximumLength = size;
+                break;
+            }
+            size *= 2;
+            ustrModule.Buffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, size*sizeof(WCHAR));
+        } while(TRUE);
+        
+        /* Ask win32k */
+        param.bIcon = bIcon;
+        param.cx = cxDesired;
+        param.cy = cyDesired;
+        hCurIcon = NtUserFindExistingCursorIcon(&ustrModule, &ustrRsrc, &param);
+        if(hCurIcon)
+        {
+            /* Woohoo, got it! */
+            TRACE("MATCH!\n");
+            HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
+            return hCurIcon;
+        }
+    }
+
     /* Find resource ID */
     hrsrc = FindResourceW(
         hinst,
@@ -300,57 +813,45 @@ CURSORICON_LoadImageW(
     
     /* We let FindResource, LoadResource, etc. call SetLastError */
     if(!hrsrc)
-        return NULL;
-    
-    /* Fix width/height */
-    if(fuLoad & LR_DEFAULTSIZE)
-    {
-        if(!cxDesired) cxDesired = GetSystemMetrics(bIcon ? SM_CXICON : SM_CXCURSOR);
-        if(!cyDesired) cyDesired = GetSystemMetrics(bIcon ? SM_CYICON : SM_CYCURSOR);
-    }
-    
-    /* If LR_SHARED is set, we must check for the cache */
-    hCurIcon = NtUserFindExistingCursorIcon(hinst, hrsrc, cxDesired, cyDesired);
-    if(hCurIcon)
-        return hCurIcon;
+        goto done;
     
     handle = LoadResource(hinst, hrsrc);
     if(!handle)
-        return NULL;
+        goto done;
     
     dir = LockResource(handle);
-        if(!dir) return NULL;
+    if(!dir)
+        goto done;
     
-    /* For now, take the first entry */
-    wResId = dir->idEntries[0].wResId;
+    wResId = LookupIconIdFromDirectoryEx((PBYTE)dir, bIcon, cxDesired, cyDesired, fuLoad & LR_MONOCHROME);
     FreeResource(handle);
     
     /* Get the relevant resource pointer */
-    hrsrc2 = FindResourceW(
+    hrsrc = FindResourceW(
         hinst,
         MAKEINTRESOURCEW(wResId),
         (LPWSTR)(bIcon ? RT_ICON : RT_CURSOR));
-    if(!hrsrc2)
-        return NULL;
+    if(!hrsrc)
+        goto done;
     
-    handle = LoadResource(hinst, hrsrc2);
+    handle = LoadResource(hinst, hrsrc);
     if(!handle)
-        return NULL;
+        goto done;
     
     bits = LockResource(handle);
     if(!bits)
     {
         FreeResource(handle);
-        return NULL;
+        goto done;
     }
     
-    /* Get the hospot */
+    /* Get the hotspot */
     if(bIcon)
     {
         ii.xHotspot = cxDesired/2;
         ii.yHotspot = cyDesired/2;
     }
-    else
+    if(!bIcon)
     {
         SHORT* ptr = (SHORT*)bits;
         ii.xHotspot = ptr[0];
@@ -369,16 +870,20 @@ CURSORICON_LoadImageW(
     FreeResource( handle );
     
     if(!bStatus)
-        return NULL;
+        goto done;
     
     /* Create the handle */
     hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1);
     if(!hCurIcon)
-        return NULL;
+    {
+        DeleteObject(ii.hbmMask);
+        if(ii.hbmColor) DeleteObject(ii.hbmColor);
+        goto done;
+    }
     
     /* Tell win32k */
     if(fuLoad & LR_SHARED)
-        bStatus = NtUserSetCursorIconData(hCurIcon, hinst, hrsrc, &ii);
+        bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &ii);
     else
         bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &ii);
     
@@ -389,11 +894,334 @@ CURSORICON_LoadImageW(
     }
     
     DeleteObject(ii.hbmMask);
-    DeleteObject(ii.hbmColor);
-    
+    if(ii.hbmColor) DeleteObject(ii.hbmColor);
+
+done:
+    if(ustrModule.Buffer)
+        HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
     return hCurIcon;
 }
 
+static
+HBITMAP
+BITMAP_CopyImage(
+  _In_  HBITMAP hbmp,
+  _In_  int cxDesired,
+  _In_  int cyDesired,
+  _In_  UINT fuFlags
+)
+{
+    HBITMAP res = NULL;
+    DIBSECTION ds;
+    int objSize;
+    BITMAPINFO * bi;
+
+    objSize = GetObjectW( hbmp, sizeof(ds), &ds );
+    if (!objSize) return 0;
+    if ((cxDesired < 0) || (cyDesired < 0)) return 0;
+
+    if (fuFlags & LR_COPYFROMRESOURCE)
+    {
+        FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
+    }
+    
+    if (fuFlags & LR_COPYRETURNORG)
+    {
+        FIXME("The flag LR_COPYRETURNORG is not implemented for bitmaps\n");
+    }
+
+    if (cxDesired == 0) cxDesired = ds.dsBm.bmWidth;
+    if (cyDesired == 0) cyDesired = ds.dsBm.bmHeight;
+
+    /* Allocate memory for a BITMAPINFOHEADER structure and a
+       color table. The maximum number of colors in a color table
+       is 256 which corresponds to a bitmap with depth 8.
+       Bitmaps with higher depths don't have color tables. */
+    bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
+    if (!bi) return 0;
+
+    bi->bmiHeader.biSize        = sizeof(bi->bmiHeader);
+    bi->bmiHeader.biPlanes      = ds.dsBm.bmPlanes;
+    bi->bmiHeader.biBitCount    = ds.dsBm.bmBitsPixel;
+    bi->bmiHeader.biCompression = BI_RGB;
+
+    if (fuFlags & LR_CREATEDIBSECTION)
+    {
+        /* Create a DIB section. LR_MONOCHROME is ignored */
+        void * bits;
+        HDC dc = CreateCompatibleDC(NULL);
+
+        if (objSize == sizeof(DIBSECTION))
+        {
+            /* The source bitmap is a DIB.
+               Get its attributes to create an exact copy */
+            memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
+        }
+
+        /* Get the color table or the color masks */
+        GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
+
+        bi->bmiHeader.biWidth  = cxDesired;
+        bi->bmiHeader.biHeight = cyDesired;
+        bi->bmiHeader.biSizeImage = 0;
+
+        res = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+        DeleteDC(dc);
+    }
+    else
+    {
+        /* Create a device-dependent bitmap */
+
+        BOOL monochrome = (fuFlags & LR_MONOCHROME);
+
+        if (objSize == sizeof(DIBSECTION))
+        {
+            /* The source bitmap is a DIB section.
+               Get its attributes */
+            HDC dc = CreateCompatibleDC(NULL);
+            bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
+            bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
+            GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
+            DeleteDC(dc);
+
+            if (!monochrome && ds.dsBm.bmBitsPixel == 1)
+            {
+                /* Look if the colors of the DIB are black and white */
+
+                monochrome = 
+                      (bi->bmiColors[0].rgbRed == 0xff
+                    && bi->bmiColors[0].rgbGreen == 0xff
+                    && bi->bmiColors[0].rgbBlue == 0xff
+                    && bi->bmiColors[0].rgbReserved == 0
+                    && bi->bmiColors[1].rgbRed == 0
+                    && bi->bmiColors[1].rgbGreen == 0
+                    && bi->bmiColors[1].rgbBlue == 0
+                    && bi->bmiColors[1].rgbReserved == 0)
+                    ||
+                      (bi->bmiColors[0].rgbRed == 0
+                    && bi->bmiColors[0].rgbGreen == 0
+                    && bi->bmiColors[0].rgbBlue == 0
+                    && bi->bmiColors[0].rgbReserved == 0
+                    && bi->bmiColors[1].rgbRed == 0xff
+                    && bi->bmiColors[1].rgbGreen == 0xff
+                    && bi->bmiColors[1].rgbBlue == 0xff
+                    && bi->bmiColors[1].rgbReserved == 0);
+            }
+        }
+        else if (!monochrome)
+        {
+            monochrome = ds.dsBm.bmBitsPixel == 1;
+        }
+
+        if (monochrome)
+        {
+            res = CreateBitmap(cxDesired, cyDesired, 1, 1, NULL);
+        }
+        else
+        {
+            HDC screenDC = GetDC(NULL);
+            res = CreateCompatibleBitmap(screenDC, cxDesired, cyDesired);
+            ReleaseDC(NULL, screenDC);
+        }
+    }
+
+    if (res)
+    {
+        /* Only copy the bitmap if it's a DIB section or if it's
+           compatible to the screen */
+        BOOL copyContents;
+
+        if (objSize == sizeof(DIBSECTION))
+        {
+            copyContents = TRUE;
+        }
+        else
+        {
+            HDC screenDC = GetDC(NULL);
+            int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
+            ReleaseDC(NULL, screenDC);
+
+            copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
+        }
+
+        if (copyContents)
+        {
+            /* The source bitmap may already be selected in a device context,
+               use GetDIBits/StretchDIBits and not StretchBlt  */
+
+            HDC dc;
+            void * bits;
+
+            dc = CreateCompatibleDC(NULL);
+
+            bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
+            bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
+            bi->bmiHeader.biSizeImage = 0;
+            bi->bmiHeader.biClrUsed = 0;
+            bi->bmiHeader.biClrImportant = 0;
+
+            /* Fill in biSizeImage */
+            GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
+            bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bi->bmiHeader.biSizeImage);
+
+            if (bits)
+            {
+                HBITMAP oldBmp;
+
+                /* Get the image bits of the source bitmap */
+                GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
+
+                /* Copy it to the destination bitmap */
+                oldBmp = SelectObject(dc, res);
+                StretchDIBits(dc, 0, 0, cxDesired, cyDesired,
+                              0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
+                              bits, bi, DIB_RGB_COLORS, SRCCOPY);
+                SelectObject(dc, oldBmp);
+
+                HeapFree(GetProcessHeap(), 0, bits);
+            }
+
+            DeleteDC(dc);
+        }
+
+        if (fuFlags & LR_COPYDELETEORG)
+        {
+            DeleteObject(hbmp);
+        }
+    }
+    HeapFree(GetProcessHeap(), 0, bi);
+    return res;
+}
+
+static
+HICON
+CURSORICON_CopyImage(
+  _In_  HICON hicon,
+  _In_  BOOL  bIcon,
+  _In_  int cxDesired,
+  _In_  int cyDesired,
+  _In_  UINT fuFlags
+)
+{
+    HICON ret = NULL;
+    ICONINFO ii;
+    
+    if(fuFlags & LR_COPYFROMRESOURCE)
+    {
+        /* Get the icon module/resource names */
+        UNICODE_STRING ustrModule;
+        UNICODE_STRING ustrRsrc;
+        PVOID pvBuf;
+        HMODULE hModule;
+        
+        ustrModule.MaximumLength = MAX_PATH;
+        ustrRsrc.MaximumLength = 256;
+        
+        ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength * sizeof(WCHAR));
+        if(!ustrModule.Buffer)
+        {
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            return NULL;
+        }
+        /* Keep track of the buffer for the resource, NtUserGetIconInfo might overwrite it */
+        pvBuf = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(WCHAR));
+        if(!pvBuf)
+        {
+            HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            return NULL;
+        }
+        ustrRsrc.Buffer = pvBuf;
+        
+        do
+        {
+            if(!NtUserGetIconInfo(hicon, NULL, &ustrModule, &ustrRsrc, NULL, FALSE))
+            {
+                HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
+                HeapFree(GetProcessHeap(), 0, pvBuf);
+                return NULL;
+            }
+            
+            if((ustrModule.Length < ustrModule.MaximumLength) && (ustrRsrc.Length < ustrRsrc.MaximumLength))
+            {
+                /* Buffers were big enough */
+                break;
+            }
+            
+            /* Find which buffer were too small */
+            if(ustrModule.Length == ustrModule.MaximumLength)
+            {
+                PWSTR newBuffer;
+                ustrModule.MaximumLength *= 2;
+                newBuffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, ustrModule.MaximumLength * sizeof(WCHAR));
+                if(!ustrModule.Buffer)
+                {
+                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                    goto leave;
+                }
+                ustrModule.Buffer = newBuffer;
+            }
+            
+            if(ustrRsrc.Length == ustrRsrc.MaximumLength)
+            {
+                ustrRsrc.MaximumLength *= 2;
+                pvBuf = HeapReAlloc(GetProcessHeap(), 0, ustrRsrc.Buffer, ustrRsrc.MaximumLength * sizeof(WCHAR));
+                if(!pvBuf)
+                {
+                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                    goto leave;
+                }
+                ustrRsrc.Buffer = pvBuf;
+            }
+        } while(TRUE);
+        
+        /* NULL-terminate our strings */
+        ustrModule.Buffer[ustrModule.Length] = 0;
+        if(!IS_INTRESOURCE(ustrRsrc.Buffer))
+            ustrRsrc.Buffer[ustrRsrc.Length] = 0;
+        
+        /* Get the module handle */
+        if(!GetModuleHandleExW(0, ustrModule.Buffer, &hModule))
+        {
+            /* This hould never happen */
+            SetLastError(ERROR_INVALID_PARAMETER);
+            goto leave;
+        }
+        
+        /* Call the relevant function */
+        ret = CURSORICON_LoadImageW(hModule, ustrRsrc.Buffer, cxDesired, cyDesired, fuFlags & LR_DEFAULTSIZE, bIcon);
+        
+        FreeLibrary(hModule);
+        
+        /* If we're here, that means that the passed icon is shared. Don't destroy it, even if LR_COPYDELETEORG is specified */
+    leave:
+        HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
+        HeapFree(GetProcessHeap(), 0, pvBuf);
+        
+        return ret;
+    }
+    
+    /* This is a regular copy */
+    if(fuFlags & ~LR_COPYDELETEORG)
+        FIXME("Unimplemented flags: 0x%08x\n", fuFlags);
+    
+    if(!GetIconInfo(hicon, &ii))
+    {
+        ERR("GetIconInfo failed.\n");
+        return NULL;
+    }
+    
+    ret = CreateIconIndirect(&ii);
+    
+    DeleteObject(ii.hbmMask);
+    if(ii.hbmColor) DeleteObject(ii.hbmColor);
+    
+    if(ret && (fuFlags & LR_COPYDELETEORG))
+        DestroyIcon(hicon);
+    
+    return hicon;
+}
+
 /************* PUBLIC FUNCTIONS *******************/
 
 HANDLE WINAPI CopyImage(
@@ -404,7 +1232,19 @@ HANDLE WINAPI CopyImage(
   _In_  UINT fuFlags
 )
 {
-    UNIMPLEMENTED;
+    TRACE("hImage=%p, uType=%u, cxDesired=%d, cyDesired=%d, fuFlags=%x\n",
+        hImage, uType, cxDesired, cyDesired, fuFlags);
+    switch(uType)
+    {
+        case IMAGE_BITMAP:
+            return BITMAP_CopyImage(hImage, cxDesired, cyDesired, fuFlags);
+        case IMAGE_CURSOR:
+        case IMAGE_ICON:
+            return CURSORICON_CopyImage(hImage, uType == IMAGE_ICON, cxDesired, cyDesired, fuFlags);
+        default:
+            SetLastError(ERROR_INVALID_PARAMETER);
+            break;
+    }
     return NULL;
 }
 
@@ -438,8 +1278,9 @@ BOOL WINAPI DrawIconEx(
   _In_      UINT diFlags
 )
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    return NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
+                            istepIfAniCur, hbrFlickerFreeDraw, diFlags,
+                            0, 0);
 }
 
 BOOL WINAPI GetIconInfo(
@@ -447,16 +1288,14 @@ BOOL WINAPI GetIconInfo(
   _Out_  PICONINFO piconinfo
 )
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    return NtUserGetIconInfo(hIcon, piconinfo, NULL, NULL, NULL, FALSE);
 }
 
 BOOL WINAPI DestroyIcon(
   _In_  HICON hIcon
 )
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    return NtUserDestroyCursor(hIcon, FALSE);
 }
 
 HICON WINAPI LoadIconA(
@@ -631,8 +1470,9 @@ int WINAPI LookupIconIdFromDirectory(
   _In_  BOOL fIcon
 )
 {
-    UNIMPLEMENTED;
-    return 0;
+    return LookupIconIdFromDirectoryEx( presbits, fIcon,
+           fIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
+           fIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), fIcon ? 0 : LR_MONOCHROME );
 }
 
 int WINAPI LookupIconIdFromDirectoryEx(
@@ -643,8 +1483,134 @@ int WINAPI LookupIconIdFromDirectoryEx(
   _In_  UINT Flags
 )
 {
-    UNIMPLEMENTED;
-    return 0;
+    WORD bppDesired;
+    CURSORICONDIR* dir = (CURSORICONDIR*)presbits;
+    CURSORICONDIRENTRY* entry;
+    int i, numMatch, iIndex = -1;
+    WORD width, height;
+    USHORT bitcount;
+    ULONG cxyDiff, cxyDiffTmp;
+    
+    TRACE("%p, %x, %i, %i, %x.\n", presbits, fIcon, cxDesired, cyDesired, Flags);
+    
+    if(!(dir && !dir->idReserved && (dir->idType & 3)))
+    {
+        WARN("Invalid resource.\n");
+        return 0;
+    }
+    
+    /* idType == 2 is for cursors, 1 for icons */
+    /*if(fIcon)
+    {
+        if(dir->idType == 2)
+        {
+            WARN("An icon was asked for a cursor resource.\n");
+            return 0;
+        }
+    }
+    else if(dir->idType == 1)
+    {
+        WARN("A cursor was asked for an icon resource.\n");
+        return 0;
+    }*/
+    
+    if(Flags & LR_MONOCHROME)
+        bppDesired = 1;
+    else
+    {
+        HDC icScreen;
+        icScreen = CreateICW(DISPLAYW, NULL, NULL, NULL);
+        if(!icScreen)
+            return FALSE;
+        
+        bppDesired = GetDeviceCaps(icScreen, BITSPIXEL);
+        DeleteDC(icScreen);
+    }
+
+    /* Find the best match for the desired size */
+    cxyDiff = 0xFFFFFFFF;
+    numMatch = 0;
+    for(i = 0; i < dir->idCount; i++)
+    {
+        entry = &dir->idEntries[i];
+        width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
+        /* Height is twice as big in cursor resources */
+        height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
+        /* 0 represents 256 */
+        if(!width) width = 256;
+        if(!height) height = 256;
+        /* Let it be a 1-norm */
+        cxyDiffTmp = max(abs(width - cxDesired), abs(height - cyDesired));
+        if( cxyDiffTmp > cxyDiff)
+            continue;
+        if( cxyDiffTmp == cxyDiff)
+        {
+            numMatch++;
+            continue;
+        }
+        iIndex = i;
+        numMatch = 1;
+        cxyDiff = cxyDiffTmp;
+    }
+    
+    if(numMatch == 1)
+    {
+        /* Only one entry fit the asked dimensions */
+        return dir->idEntries[iIndex].wResId;
+    }
+    
+    bitcount = 0;
+    iIndex = -1;
+    /* Now find the entry with the best depth */
+    for(i = 0; i < dir->idCount; i++)
+    {
+        entry = &dir->idEntries[i];
+        width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
+        height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
+        /* 0 represents 256 */
+        if(!width) width = 256;
+        if(!height) height = 256;
+        /* Check if this is the best match we had */
+        cxyDiffTmp = max(abs(width - cxDesired), abs(height - cyDesired));
+        if(cxyDiffTmp != cxyDiff)
+            continue;
+        /* Exact match? */
+        if(entry->wBitCount == bppDesired)
+            return entry->wResId;
+        /* We take the highest possible but smaller  than the display depth */
+        if((entry->wBitCount > bitcount) && (entry->wBitCount < bppDesired))
+        {
+            iIndex = i;
+            bitcount = entry->wBitCount;
+        }
+    }
+    
+    if(iIndex >= 0)
+        return dir->idEntries[iIndex].wResId;
+    
+    /* No inferior or equal depth available. Get the smallest one */
+    bitcount = 0x7FFF;
+    for(i = 0; i < dir->idCount; i++)
+    {
+        entry = &dir->idEntries[i];
+        width = fIcon ? entry->ResInfo.icon.bWidth : entry->ResInfo.cursor.wWidth;
+        height = fIcon ? entry->ResInfo.icon.bHeight : entry->ResInfo.cursor.wHeight/2;
+        /* 0 represents 256 */
+        if(!width) width = 256;
+        if(!height) height = 256;
+        /* Check if this is the best match we had */
+        cxyDiffTmp = max(abs(width - cxDesired), abs(height - cyDesired));
+        if(cxyDiffTmp != cxyDiff)
+            continue;
+        /* Check the bit depth */
+        if(entry->wBitCount < bitcount)
+        {
+            iIndex = i;
+            bitcount = entry->wBitCount;
+        }
+    }
+    
+    return dir->idEntries[iIndex].wResId;
 }
 
 HICON WINAPI CreateIcon(
@@ -657,8 +1623,32 @@ HICON WINAPI CreateIcon(
   _In_      const BYTE *lpbXORbits
 )
 {
-    UNIMPLEMENTED;
-    return NULL;
+    ICONINFO iinfo;
+    HICON hIcon;
+
+    TRACE_(icon)("%dx%d, planes %d, bpp %d, xor %p, and %p\n",
+                 nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits, lpbANDbits);
+
+    iinfo.fIcon = TRUE;
+    iinfo.xHotspot = nWidth / 2;
+    iinfo.yHotspot = nHeight / 2;
+    if (cPlanes * cBitsPixel > 1)
+    {
+        iinfo.hbmColor = CreateBitmap( nWidth, nHeight, cPlanes, cBitsPixel, lpbXORbits );
+        iinfo.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpbANDbits );
+    }
+    else
+    {
+        iinfo.hbmMask = CreateBitmap( nWidth, nHeight * 2, 1, 1, lpbANDbits );
+        iinfo.hbmColor = NULL;
+    }
+
+    hIcon = CreateIconIndirect( &iinfo );
+
+    DeleteObject( iinfo.hbmMask );
+    if (iinfo.hbmColor) DeleteObject( iinfo.hbmColor );
+
+    return hIcon;
 }
 
 HICON WINAPI CreateIconFromResource(
@@ -681,16 +1671,60 @@ HICON WINAPI CreateIconFromResourceEx(
   _In_  UINT uFlags
 )
 {
-    UNIMPLEMENTED;
-    return NULL;
+    ICONINFO ii;
+    HICON hIcon;
+    
+    if(uFlags)
+        FIXME("uFlags 0x%08x ignored.\n", uFlags);
+    
+    if(fIcon)
+    {
+        ii.xHotspot = cxDesired/2;
+        ii.yHotspot = cyDesired/2;
+    }
+    else
+    {
+        WORD* pt = (WORD*)pbIconBits;
+        ii.xHotspot = *pt++;
+        ii.yHotspot = *pt++;
+        pbIconBits = (PBYTE)pt;
+    }
+    ii.fIcon = fIcon;
+    
+    if(!CURSORICON_GetIconInfoFromBMI(&ii, (BITMAPINFO*)pbIconBits, cxDesired, cyDesired))
+        return NULL;
+    
+    hIcon = CreateIconIndirect(&ii);
+    
+    /* Clean up */
+    DeleteObject(ii.hbmMask);
+    if(ii.hbmColor) DeleteObject(ii.hbmColor);
+    
+    return hIcon;
 }
 
 HICON WINAPI CreateIconIndirect(
   _In_  PICONINFO piconinfo
 )
 {
-    UNIMPLEMENTED;
-    return NULL;
+    /* As simple as creating a handle, and let win32k deal with the bitmaps */
+    HICON hiconRet;
+    
+    TRACE("%p.\n", piconinfo);
+    
+    hiconRet = NtUserxCreateEmptyCurObject(piconinfo->fIcon ? 0 : 1);
+    if(!hiconRet)
+        return NULL;
+    
+    if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, piconinfo))
+    {
+        NtUserDestroyCursor(hiconRet, FALSE);
+        hiconRet = NULL;
+    }
+    
+    TRACE("Returning 0x%08x.\n", hiconRet);
+    
+    return hiconRet;
 }
 
 HCURSOR WINAPI CreateCursor(
@@ -703,8 +1737,21 @@ HCURSOR WINAPI CreateCursor(
   _In_      const VOID *pvXORPlane
 )
 {
-    UNIMPLEMENTED;
-    return NULL;
+    ICONINFO info;
+    HCURSOR hCursor;
+
+    TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n",
+                    nWidth, nHeight, xHotSpot, yHotSpot, pvXORPlane, pvANDPlane);
+
+    info.fIcon = FALSE;
+    info.xHotspot = xHotSpot;
+    info.yHotspot = yHotSpot;
+    info.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, pvANDPlane );
+    info.hbmColor = CreateBitmap( nWidth, nHeight, 1, 1, pvXORPlane );
+    hCursor = CreateIconIndirect( &info );
+    DeleteObject( info.hbmMask );
+    DeleteObject( info.hbmColor );
+    return hCursor;
 }
 
 BOOL WINAPI SetSystemCursor(
@@ -729,8 +1776,7 @@ BOOL WINAPI GetCursorPos(
   _Out_  LPPOINT lpPoint
 )
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    return NtUserxGetCursorPos(lpPoint);
 }
 
 int WINAPI ShowCursor(
@@ -751,6 +1797,5 @@ BOOL WINAPI DestroyCursor(
   _In_  HCURSOR hCursor
 )
 {
-    UNIMPLEMENTED;
-    return FALSE;
+    return NtUserDestroyCursor(hCursor, FALSE);
 }
index 1ce55fd..0df3dd3 100644 (file)
@@ -2162,7 +2162,7 @@ GetDlgItemInt(
         result = strtol( str, &endptr, 10 );
         if (!endptr || (endptr == str))  /* Conversion was unsuccessful */
             return 0;
-        if (((result == LONG_MIN) || (result == LONG_MAX)) && (errno == ERANGE) )
+        if (((result == LONG_MIN) || (result == LONG_MAX)))
             return 0;
     }
     else
@@ -2170,7 +2170,7 @@ GetDlgItemInt(
         result = strtoul( str, &endptr, 10 );
         if (!endptr || (endptr == str))  /* Conversion was unsuccessful */
             return 0;
-        if ((result == ULONG_MAX) && (errno == ERANGE) ) return 0;
+        if (result == ULONG_MAX) return 0;
     }
     if (lpTranslated) *lpTranslated = TRUE;
     return (UINT)result;
index d24eb03..783d7c8 100644 (file)
@@ -792,7 +792,7 @@ static LONG MDICascade( HWND client, MDICLIENTINFO *ci )
 static void MDITile( HWND client, MDICLIENTINFO *ci, WPARAM wParam )
 {
     HWND *win_array;
-    int i, total;
+    int i, total, rows, columns;
     BOOL has_icons = FALSE;
 
     if (ci->hwndChildMaximized)
@@ -803,7 +803,7 @@ static void MDITile( HWND client, MDICLIENTINFO *ci, WPARAM wParam )
     if (!(win_array = WIN_ListChildren( client ))) return;
 
     /* remove all the windows we don't want */
-    for (i = total = 0; win_array[i]; i++)
+    for (i = total = rows = 0; win_array[i]; i++)
     {
         if (!IsWindowVisible( win_array[i] )) continue;
         if (GetWindow( win_array[i], GW_OWNER )) continue; /* skip owned windows (icon titles) */
@@ -813,6 +813,7 @@ static void MDITile( HWND client, MDICLIENTINFO *ci, WPARAM wParam )
             continue;
         }
         if ((wParam & MDITILE_SKIPDISABLED) && !IsWindowEnabled( win_array[i] )) continue;
+        if(total == (rows * (rows + 2))) rows++; /* total+1 == (rows+1)*(rows+1) */
         win_array[total++] = win_array[i];
     }
     win_array[total] = 0;
@@ -824,11 +825,11 @@ static void MDITile( HWND client, MDICLIENTINFO *ci, WPARAM wParam )
         HWND *pWnd = win_array;
         RECT rect;
         int x, y, xsize, ysize;
-        int rows, columns, r, c, i;
+        int r, c, i;
 
         GetClientRect(client,&rect);
-        rows    = (int) sqrt((double)total);
-        columns = total / rows;
+        columns = total/rows;
+        //while(total < rows*columns) rows++;
 
         if( wParam & MDITILE_HORIZONTAL )  /* version >= 3.1 */
         {
@@ -1604,8 +1605,8 @@ LRESULT WINAPI DefMDIChildProcW( HWND hwnd, UINT message,
 #ifndef __REACTOS__
     case WM_SETVISIBLE:
 #endif
-        if (ci->hwndChildMaximized) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
-        else MDI_PostUpdate(client, ci, SB_BOTH+1);
+        /*if (ci->hwndChildMaximized) ci->mdiFlags &= ~MDIF_NEEDUPDATE;
+        else*/ MDI_PostUpdate(client, ci, SB_BOTH+1);
         break;
 
     case WM_SIZE:
@@ -1843,7 +1844,6 @@ void WINAPI CalcChildScroll( HWND hwnd, INT scroll )
         }
         HeapFree( GetProcessHeap(), 0, list );
     }
-    MapWindowPoints( 0, hwnd, (POINT *)&childRect, 2 );
     UnionRect( &childRect, &clientRect, &childRect );
 
     /* set common info values */