Commit in reactos/lib/user32 on MAIN
include/winsta.h+10-11.1 -> 1.2
misc/desktop.c+12-131.33 -> 1.34
    /winsta.c+173-321.16 -> 1.17
+195-46
3 modified files
Implement EnumDesktopsA/W and EnumWindowStationsA, rewrite of
EnumWindowStationsW

reactos/lib/user32/include
winsta.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- winsta.h	12 Jun 2001 17:50:26 -0000	1.1
+++ winsta.h	21 Aug 2004 19:50:39 -0000	1.2
@@ -1,6 +1,15 @@
-/*
+/* $Id: winsta.h,v 1.2 2004/08/21 19:50:39 gvg Exp $
+ *
  * COPYRIGHT:   See COPYING in the top level directory
  * PROJECT:     ReactOS user32.dll
  * FILE:        include/winsta.h
  * PURPOSE:     Window stations
  */
+
+#ifndef USER32_WINSTA_H_INCLUDED
+#define USER32_WINSTA_H_INCLUDED
+
+extern BOOL FASTCALL EnumNamesA(HWINSTA WindowStation, NAMEENUMPROCA EnumFunc, LPARAM Context, BOOL Desktops);
+extern BOOL FASTCALL EnumNamesW(HWINSTA WindowStation, NAMEENUMPROCW EnumFunc, LPARAM Context, BOOL Desktops);
+
+#endif /* USER32_WINSTA_H_INCLUDED */

reactos/lib/user32/misc
desktop.c 1.33 -> 1.34
diff -u -r1.33 -r1.34
--- desktop.c	17 Aug 2004 21:47:36 -0000	1.33
+++ desktop.c	21 Aug 2004 19:50:39 -0000	1.34
@@ -1,4 +1,4 @@
-/* $Id: desktop.c,v 1.33 2004/08/17 21:47:36 weiden Exp $
+/* $Id: desktop.c,v 1.34 2004/08/21 19:50:39 gvg Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll
@@ -10,6 +10,7 @@
  */
 
 #include "user32.h"
+#include "winsta.h"
 #include <string.h>
 #include <debug.h>
 #include <rosrtl/devmode.h>
@@ -370,32 +371,30 @@
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
 EnumDesktopsA(
-  HWINSTA hwinsta,
-  DESKTOPENUMPROCA lpEnumFunc,
-  LPARAM lParam)
+  HWINSTA WindowStation,
+  DESKTOPENUMPROCA EnumFunc,
+  LPARAM Context)
 {
-  UNIMPLEMENTED;
-  return FALSE;
+   return EnumNamesA(WindowStation, EnumFunc, Context, TRUE);
 }
 
 
 /*
- * @unimplemented
+ * @implemented
  */
 BOOL
 STDCALL
 EnumDesktopsW(
-  HWINSTA hwinsta,
-  DESKTOPENUMPROCW lpEnumFunc,
-  LPARAM lParam)
+  HWINSTA WindowStation,
+  DESKTOPENUMPROCW EnumFunc,
+  LPARAM Context)
 {
-  UNIMPLEMENTED;
-  return FALSE;
+   return EnumNamesW(WindowStation, EnumFunc, Context, TRUE);
 }
 
 

reactos/lib/user32/misc
winsta.c 1.16 -> 1.17
diff -u -r1.16 -r1.17
--- winsta.c	15 Aug 2004 21:36:28 -0000	1.16
+++ winsta.c	21 Aug 2004 19:50:39 -0000	1.17
@@ -1,4 +1,4 @@
-/* $Id: winsta.c,v 1.16 2004/08/15 21:36:28 chorns Exp $
+/* $Id: winsta.c,v 1.17 2004/08/21 19:50:39 gvg Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll
@@ -76,59 +76,200 @@
 				   lpsa, 0, 0, 0);
 }
 
-
 /*
- * @unimplemented
+ * Common code for EnumDesktopsA/W and EnumWindowStationsA/W
  */
-BOOL STDCALL
-EnumWindowStationsA(WINSTAENUMPROCA lpEnumFunc,
-		    LPARAM lParam)
-{
-  UNIMPLEMENTED;
-  return FALSE;
+BOOL FASTCALL
+EnumNamesW(HWINSTA WindowStation,
+           NAMEENUMPROCW EnumFunc,
+	   LPARAM Context,
+           BOOL Desktops)
+{
+   char Buffer[256];
+   PVOID NameList;
+   PWCHAR Name;
+   NTSTATUS Status;
+   ULONG RequiredSize;
+   ULONG CurrentEntry, EntryCount;
+   BOOL Ret;
+
+   /*
+    * Check parameters
+    */
+   if (NULL == WindowStation && Desktops)
+   {
+      SetLastError(ERROR_INVALID_HANDLE);
+      return FALSE;
+   }
+
+   /*
+    * Try with fixed-size buffer
+    */
+   Status = NtUserBuildNameList(WindowStation, sizeof(Buffer), Buffer, &RequiredSize);
+   if (NT_SUCCESS(Status))
+   {
+      /* Fixed-size buffer is large enough */
+      NameList = (PWCHAR) Buffer;
+   }
+   else if (Status == STATUS_BUFFER_TOO_SMALL)
+   {
+      /* Allocate a larger buffer */
+      NameList = HeapAlloc(GetProcessHeap(), 0, RequiredSize);
+      if (NULL == NameList)
+      {
+         return FALSE;
+      }
+      /* Try again */
+      Status = NtUserBuildNameList(WindowStation, RequiredSize, NameList, NULL);
+      if (! NT_SUCCESS(Status))
+      {
+         HeapFree(GetProcessHeap(), 0, NameList);
+         SetLastError(RtlNtStatusToDosError(Status));
+         return FALSE;
+      }
+   }
+   else
+   {
+      /* Some unrecognized error occured */
+      SetLastError(RtlNtStatusToDosError(Status));
+      return FALSE;
+   }
+
+   /*
+    * Enum the names one by one
+    */
+   EntryCount = *((DWORD *) NameList);
+   Name = (PWCHAR) ((PCHAR) NameList + sizeof(DWORD));
+   Ret = TRUE;
+   for (CurrentEntry = 0; CurrentEntry < EntryCount && Ret; ++CurrentEntry)
+   {
+      Ret = (*EnumFunc)(Name, Context);
+      Name += wcslen(Name) + 1;
+   }
+
+   /*
+    * Cleanup
+    */
+   if (NameList != Buffer)
+   {
+      HeapFree(GetProcessHeap(), 0, NameList);
+   }
+
+   return Ret;
 }
 
 
+/* For W->A conversion */
+typedef struct tagENUMNAMESASCIICONTEXT
+{
+   NAMEENUMPROCA UserEnumFunc;
+   LPARAM UserContext;
+} ENUMNAMESASCIICONTEXT, *PENUMNAMESASCIICONTEXT;
+
 /*
- * @unimplemented
+ * Callback used by Ascii versions. Converts the Unicode name to
+ * Ascii and then calls the user callback
  */
-BOOL STDCALL
-EnumWindowStationsW(WINSTAENUMPROCW lpEnumFunc,
-		    LPARAM lParam)
+BOOL CALLBACK
+EnumNamesCallback(LPWSTR Name, LPARAM Param)
 {
-   PWCHAR Buffer;
-   NTSTATUS Status;
-   ULONG dwRequiredSize;
-   ULONG CurrentEntry, EntryCount;
+   PENUMNAMESASCIICONTEXT Context = (PENUMNAMESASCIICONTEXT) Param;
+   char FixedNameA[32];
+   LPSTR NameA;
+   int Len;
+   BOOL Ret;
 
-   Buffer = HeapAlloc(GetProcessHeap(), 0, 200);
-   if (Buffer == NULL)
+   /*
+    * Determine required size of Ascii string and see if we can use
+    * fixed buffer
+    */
+   Len = WideCharToMultiByte(CP_ACP, 0, Name, -1, NULL, 0, NULL, NULL);
+   if (Len <= 0)
    {
+      /* Some strange error occured */
       return FALSE;
    }
-   Status = NtUserBuildNameList(0, 200, Buffer, &dwRequiredSize);
-   if (Status == STATUS_BUFFER_TOO_SMALL)
+   else if (Len <= sizeof(FixedNameA))
    {
-      Buffer = HeapReAlloc(GetProcessHeap(), 0, Buffer, dwRequiredSize);
-      if (Buffer == NULL)
+      /* Fixed-size buffer is large enough */
+      NameA = FixedNameA;
+   }
+   else
+   {
+      /* Allocate a larger buffer */
+      NameA = HeapAlloc(GetProcessHeap(), 0, Len);
+      if (NULL == NameA)
       {
+         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
          return FALSE;
       }
-      Status = NtUserBuildNameList(0, dwRequiredSize, Buffer, &dwRequiredSize);
    }
-   if (Status != STATUS_SUCCESS)
+
+   /*
+    * Do the Unicode ->Ascii conversion
+    */
+   if (0 == WideCharToMultiByte(CP_ACP, 0, Name, -1, NameA, Len, NULL, NULL))
    {
-      HeapFree(GetProcessHeap(), 0, Buffer);
+      /* Something went wrong, clean up */
+      if (NameA != FixedNameA)
+      {
+         HeapFree(GetProcessHeap(), 0, NameA);
+      }
       return FALSE;
    }
-   EntryCount = *((DWORD *)Buffer);
-   Buffer += sizeof(DWORD) / sizeof(WCHAR);
-   for (CurrentEntry = 0; CurrentEntry < EntryCount; ++CurrentEntry)
+
+   /*
+    * Call user callback
+    */
+   Ret = Context->UserEnumFunc(NameA, Context->UserContext);
+
+   /*
+    * Clean up
+    */
+   if (NameA != FixedNameA)
    {
-      (*lpEnumFunc)(Buffer, lParam);
-      Buffer += wcslen(Buffer) + 1;
+      HeapFree(GetProcessHeap(), 0, NameA);
    }
-   return TRUE;
+
+   return Ret;
+}
+
+/*
+ * Common code for EnumDesktopsA and EnumWindowStationsA
+ */
+BOOL FASTCALL
+EnumNamesA(HWINSTA WindowStation,
+           NAMEENUMPROCA EnumFunc,
+	   LPARAM Context,
+           BOOL Desktops)
+{
+   ENUMNAMESASCIICONTEXT PrivateContext;
+
+   PrivateContext.UserEnumFunc = EnumFunc;
+   PrivateContext.UserContext = Context;
+
+   return EnumNamesW(WindowStation, EnumNamesCallback, (LPARAM) &PrivateContext, Desktops);
+}
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+EnumWindowStationsA(WINSTAENUMPROCA EnumFunc,
+		    LPARAM Context)
+{
+   return EnumNamesA(NULL, EnumFunc, Context, FALSE);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+EnumWindowStationsW(WINSTAENUMPROCW EnumFunc,
+		    LPARAM Context)
+{
+   return EnumNamesW(NULL, EnumFunc, Context, FALSE);
 }
 
 
CVSspam 0.2.8