reactos/lib/user32/misc
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
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);
}