Check for failed allocations. Spotted by Martin Bealby.
[reactos.git] / reactos / lib / user32 / windows / prop.c
index ee82eca..ba76be4 100644 (file)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: prop.c,v 1.2 2002/09/03 22:44:20 dwelch Exp $
+/* $Id$
  *
  * PROJECT:         ReactOS user32.dll
  * FILE:            lib/user32/windows/input.c
 
 /* INCLUDES ******************************************************************/
 
-#include <windows.h>
 #include <user32.h>
-#include <debug.h>
 
+typedef struct _PROPLISTITEM
+{
+  ATOM Atom;
+  HANDLE Data;
+} PROPLISTITEM, *PPROPLISTITEM;
+
+#define ATOM_BUFFER_SIZE 256
 
 /* FUNCTIONS *****************************************************************/
 
+/*
+ * @implemented
+ */
 int STDCALL
-EnumPropsA(HWND hWnd, PROPENUMPROC lpEnumFunc)
+EnumPropsA(HWND hWnd, PROPENUMPROCA lpEnumFunc)
 {
-  return 0;
+  PPROPLISTITEM pli, i;
+  NTSTATUS Status;
+  DWORD Count;
+  int ret = -1;
+
+  if(!lpEnumFunc)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return ret;
+  }
+
+  Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
+  if(!NT_SUCCESS(Status))
+  {
+    if(Status == STATUS_INVALID_HANDLE)
+      SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+    else
+      SetLastError(RtlNtStatusToDosError(Status));
+    return ret;
+  }
+
+  if(Count > 0)
+  {
+    pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
+    if (pli == NULL)
+    {
+      SetLastError(ERROR_OUTOFMEMORY);
+      return -1;
+    }
+
+    Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
+    if(!NT_SUCCESS(Status))
+    {
+      RtlFreeHeap(GetProcessHeap(), 0, pli);
+      if(Status == STATUS_INVALID_HANDLE)
+        SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+      else
+        SetLastError(RtlNtStatusToDosError(Status));
+      return ret;
+    }
+
+    i = pli;
+    for(; Count > 0; Count--, i++)
+    {
+      char str[ATOM_BUFFER_SIZE];
+
+      if(!GlobalGetAtomNameA(i->Atom, str, ATOM_BUFFER_SIZE))
+        continue;
+
+      ret = lpEnumFunc(hWnd, str, i->Data);
+      if(!ret)
+        break;
+    }
+
+    RtlFreeHeap(GetProcessHeap(), 0, pli);
+  }
+
+  return ret;
 }
 
+
+/*
+ * @implemented
+ */
 int STDCALL
-EnumPropsExA(HWND hWnd, PROPENUMPROCEX lpEnumFunc, LPARAM lParam)
+EnumPropsExA(HWND hWnd, PROPENUMPROCEXA lpEnumFunc, LPARAM lParam)
 {
-  return 0;
+  PPROPLISTITEM pli, i;
+  NTSTATUS Status;
+  DWORD Count;
+  int ret = -1;
+
+  if(!lpEnumFunc)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return ret;
+  }
+
+  Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
+  if(!NT_SUCCESS(Status))
+  {
+    if(Status == STATUS_INVALID_HANDLE)
+      SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+    else
+      SetLastError(RtlNtStatusToDosError(Status));
+    return ret;
+  }
+
+  if(Count > 0)
+  {
+    pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
+    if (pli == NULL)
+    {
+      SetLastError(ERROR_OUTOFMEMORY);
+      return -1;
+    }
+
+    Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
+    if(!NT_SUCCESS(Status))
+    {
+      RtlFreeHeap(GetProcessHeap(), 0, pli);
+      if(Status == STATUS_INVALID_HANDLE)
+        SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+      else
+        SetLastError(RtlNtStatusToDosError(Status));
+      return ret;
+    }
+
+    i = pli;
+    for(; Count > 0; Count--, i++)
+    {
+      char str[ATOM_BUFFER_SIZE];
+
+      if(!GlobalGetAtomNameA(i->Atom, str, ATOM_BUFFER_SIZE))
+        continue;
+
+      ret = lpEnumFunc(hWnd, str, i->Data, lParam);
+      if(!ret)
+        break;
+    }
+
+    RtlFreeHeap(GetProcessHeap(), 0, pli);
+  }
+
+  return ret;
 }
 
+
+/*
+ * @implemented
+ */
 int STDCALL
-EnumPropsExW(HWND hWnd, PROPENUMPROCEX lpEnumFunc, LPARAM lParam)
+EnumPropsExW(HWND hWnd, PROPENUMPROCEXW lpEnumFunc, LPARAM lParam)
 {
-  return 0;
+  PPROPLISTITEM pli, i;
+  NTSTATUS Status;
+  DWORD Count;
+  int ret = -1;
+
+  if(!lpEnumFunc)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return ret;
+  }
+
+  Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
+  if(!NT_SUCCESS(Status))
+  {
+    if(Status == STATUS_INVALID_HANDLE)
+      SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+    else
+      SetLastError(RtlNtStatusToDosError(Status));
+    return ret;
+  }
+
+  if(Count > 0)
+  {
+    pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
+    if (pli == NULL)
+    {
+      SetLastError(ERROR_OUTOFMEMORY);
+      return -1;
+    }
+
+    Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
+    if(!NT_SUCCESS(Status))
+    {
+      RtlFreeHeap(GetProcessHeap(), 0, pli);
+      if(Status == STATUS_INVALID_HANDLE)
+        SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+      else
+        SetLastError(RtlNtStatusToDosError(Status));
+      return ret;
+    }
+
+    i = pli;
+    for(; Count > 0; Count--, i++)
+    {
+      WCHAR str[ATOM_BUFFER_SIZE];
+
+      if(!GlobalGetAtomNameW(i->Atom, str, ATOM_BUFFER_SIZE))
+        continue;
+
+      ret = lpEnumFunc(hWnd, str, i->Data, lParam);
+      if(!ret)
+        break;
+    }
+
+    RtlFreeHeap(GetProcessHeap(), 0, pli);
+  }
+
+  return ret;
 }
 
+
+/*
+ * @implemented
+ */
 int STDCALL
-EnumPropsW(HWND hWnd, PROPENUMPROC lpEnumFunc)
+EnumPropsW(HWND hWnd, PROPENUMPROCW lpEnumFunc)
 {
-  return 0;
+  PPROPLISTITEM pli, i;
+  NTSTATUS Status;
+  DWORD Count;
+  int ret = -1;
+
+  if(!lpEnumFunc)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return ret;
+  }
+
+  Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
+  if(!NT_SUCCESS(Status))
+  {
+    if(Status == STATUS_INVALID_HANDLE)
+      SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+    else
+      SetLastError(RtlNtStatusToDosError(Status));
+    return ret;
+  }
+
+  if(Count > 0)
+  {
+    pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
+    if (pli == NULL)
+    {
+      SetLastError(ERROR_OUTOFMEMORY);
+      return -1;
+    }
+
+    Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
+    if(!NT_SUCCESS(Status))
+    {
+      RtlFreeHeap(GetProcessHeap(), 0, pli);
+      if(Status == STATUS_INVALID_HANDLE)
+        SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+      else
+        SetLastError(RtlNtStatusToDosError(Status));
+      return ret;
+    }
+
+    i = pli;
+    for(; Count > 0; Count--, i++)
+    {
+      WCHAR str[ATOM_BUFFER_SIZE];
+
+      if(!GlobalGetAtomNameW(i->Atom, str, ATOM_BUFFER_SIZE))
+        continue;
+
+      ret = lpEnumFunc(hWnd, str, i->Data);
+      if(!ret)
+        break;
+    }
+
+    RtlFreeHeap(GetProcessHeap(), 0, pli);
+  }
+
+  return ret;
 }
 
+
+/*
+ * @implemented
+ */
 HANDLE STDCALL
 GetPropA(HWND hWnd, LPCSTR lpString)
 {
   PWSTR lpWString;
+  UNICODE_STRING UString;
   HANDLE Ret;
   if (HIWORD(lpString))
     {
-      lpWString = User32ConvertString(lpString);
+      RtlCreateUnicodeStringFromAsciiz(&UString, (LPSTR)lpString);
+      lpWString = UString.Buffer;
       if (lpWString == NULL)
        {
          return(FALSE);
        }
       Ret = GetPropW(hWnd, lpWString);
-      User32FreeString(lpWString);
+      RtlFreeUnicodeString(&UString);
     }
   else
     {
-      Ret = GetPropW(hWnd, lpString);
-    }  
+      Ret = GetPropW(hWnd, (LPWSTR)lpString);
+    }
   return(Ret);
 }
 
+
+/*
+ * @implemented
+ */
 HANDLE STDCALL
 GetPropW(HWND hWnd, LPCWSTR lpString)
 {
@@ -91,34 +349,44 @@ GetPropW(HWND hWnd, LPCWSTR lpString)
     }
   else
     {
-      Atom = LOWORD(lpString);
+      Atom = LOWORD((DWORD)lpString);
     }
   return(NtUserGetProp(hWnd, Atom));
 }
 
+
+/*
+ * @implemented
+ */
 HANDLE STDCALL
 RemovePropA(HWND hWnd, LPCSTR lpString)
 {
   PWSTR lpWString;
+  UNICODE_STRING UString;
   HANDLE Ret;
 
   if (HIWORD(lpString))
     {
-      lpWString = User32ConvertString(lpString);
+      RtlCreateUnicodeStringFromAsciiz(&UString, (LPSTR)lpString);
+      lpWString = UString.Buffer;
       if (lpWString == NULL)
        {
          return(FALSE);
        }
       Ret = RemovePropW(hWnd, lpWString);
-      User32FreeString(lpWString);
+      RtlFreeUnicodeString(&UString);
     }
   else
     {
-      Ret = RemovePropW(hWnd, lpWString);
+      Ret = RemovePropW(hWnd, (LPCWSTR)lpString);
     }
   return(Ret);
 }
 
+
+/*
+ * @implemented
+ */
 HANDLE STDCALL
 RemovePropW(HWND hWnd,
            LPCWSTR lpString)
@@ -130,46 +398,56 @@ RemovePropW(HWND hWnd,
     }
   else
     {
-      Atom = LOWORD(lpString);
+      Atom = LOWORD((DWORD)lpString);
     }
   return(NtUserRemoveProp(hWnd, Atom));
 }
 
-WINBOOL STDCALL
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
 SetPropA(HWND hWnd, LPCSTR lpString, HANDLE hData)
 {
   PWSTR lpWString;
+  UNICODE_STRING UString;
   BOOL Ret;
-  
+
   if (HIWORD(lpString))
     {
-      lpWString = User32ConvertString(lpString);
+      RtlCreateUnicodeStringFromAsciiz(&UString, (LPSTR)lpString);
+      lpWString = UString.Buffer;
       if (lpWString == NULL)
        {
          return(FALSE);
        }
       Ret = SetPropW(hWnd, lpWString, hData);
-      User32FreeString(lpWString);
+      RtlFreeUnicodeString(&UString);
     }
   else
     {
-      Ret = SetPropW(hWnd, lpString, hData);
+      Ret = SetPropW(hWnd, (LPWSTR)lpString, hData);
     }
   return(Ret);
 }
 
-WINBOOL STDCALL
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
 SetPropW(HWND hWnd, LPCWSTR lpString, HANDLE hData)
 {
   ATOM Atom;
   if (HIWORD(lpString))
     {
-      Atom = GlobalFindAtomW(lpString);
+      Atom = GlobalAddAtomW(lpString);
     }
   else
     {
-      Atom = LOWORD(lpString);
+      Atom = LOWORD((DWORD)lpString);
     }
-  
+
   return(NtUserSetProp(hWnd, Atom, hData));
 }