Check for failed allocations. Spotted by Martin Bealby.
[reactos.git] / reactos / lib / user32 / windows / prop.c
index a8eec2d..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.8 2003/07/10 21:04:32 chorns 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 *****************************************************************/
 
 /*
- * @unimplemented
+ * @implemented
  */
 int STDCALL
-EnumPropsA(HWND hWnd, PROPENUMPROC lpEnumFunc)
+EnumPropsA(HWND hWnd, PROPENUMPROCA lpEnumFunc)
 {
-  UNIMPLEMENTED;
-  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;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 int STDCALL
-EnumPropsExA(HWND hWnd, PROPENUMPROCEX lpEnumFunc, LPARAM lParam)
+EnumPropsExA(HWND hWnd, PROPENUMPROCEXA lpEnumFunc, LPARAM lParam)
 {
-  UNIMPLEMENTED;
-  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;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 int STDCALL
-EnumPropsExW(HWND hWnd, PROPENUMPROCEX lpEnumFunc, LPARAM lParam)
+EnumPropsExW(HWND hWnd, PROPENUMPROCEXW lpEnumFunc, LPARAM lParam)
 {
-  UNIMPLEMENTED;
-  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;
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 int STDCALL
-EnumPropsW(HWND hWnd, PROPENUMPROC lpEnumFunc)
+EnumPropsW(HWND hWnd, PROPENUMPROCW lpEnumFunc)
 {
-  UNIMPLEMENTED;
-  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;
 }
 
 
@@ -102,7 +331,7 @@ GetPropA(HWND hWnd, LPCSTR lpString)
   else
     {
       Ret = GetPropW(hWnd, (LPWSTR)lpString);
-    }  
+    }
   return(Ret);
 }
 
@@ -178,13 +407,13 @@ RemovePropW(HWND hWnd,
 /*
  * @implemented
  */
-WINBOOL STDCALL
+BOOL STDCALL
 SetPropA(HWND hWnd, LPCSTR lpString, HANDLE hData)
 {
   PWSTR lpWString;
   UNICODE_STRING UString;
   BOOL Ret;
-  
+
   if (HIWORD(lpString))
     {
       RtlCreateUnicodeStringFromAsciiz(&UString, (LPSTR)lpString);
@@ -207,18 +436,18 @@ SetPropA(HWND hWnd, LPCSTR lpString, HANDLE hData)
 /*
  * @implemented
  */
-WINBOOL STDCALL
+BOOL STDCALL
 SetPropW(HWND hWnd, LPCWSTR lpString, HANDLE hData)
 {
   ATOM Atom;
   if (HIWORD(lpString))
     {
-      Atom = GlobalFindAtomW(lpString);
+      Atom = GlobalAddAtomW(lpString);
     }
   else
     {
       Atom = LOWORD((DWORD)lpString);
     }
-  
+
   return(NtUserSetProp(hWnd, Atom, hData));
 }