Implement EnumDesktopsA/W and EnumWindowStationsA, rewrite of

EnumWindowStationsW

svn path=/trunk/; revision=10637
This commit is contained in:
Gé van Geldorp 2004-08-21 19:50:39 +00:00
parent a48867230f
commit 7f5aece68d
3 changed files with 205 additions and 56 deletions

View file

@ -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 */

View file

@ -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 @@ CreateDesktopW(LPCWSTR lpszDesktop,
/*
* @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);
}

View file

@ -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 @@ CreateWindowStationW(LPWSTR lpwinsta,
lpsa, 0, 0, 0);
}
/*
* Common code for EnumDesktopsA/W and EnumWindowStationsA/W
*/
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 CALLBACK
EnumNamesCallback(LPWSTR Name, LPARAM Param)
{
PENUMNAMESASCIICONTEXT Context = (PENUMNAMESASCIICONTEXT) Param;
char FixedNameA[32];
LPSTR NameA;
int Len;
BOOL Ret;
/*
* 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;
}
else if (Len <= sizeof(FixedNameA))
{
/* 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;
}
}
/*
* Do the Unicode ->Ascii conversion
*/
if (0 == WideCharToMultiByte(CP_ACP, 0, Name, -1, NameA, Len, NULL, NULL))
{
/* Something went wrong, clean up */
if (NameA != FixedNameA)
{
HeapFree(GetProcessHeap(), 0, NameA);
}
return FALSE;
}
/*
* Call user callback
*/
Ret = Context->UserEnumFunc(NameA, Context->UserContext);
/*
* Clean up
*/
if (NameA != FixedNameA)
{
HeapFree(GetProcessHeap(), 0, NameA);
}
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 lpEnumFunc,
LPARAM lParam)
EnumWindowStationsA(WINSTAENUMPROCA EnumFunc,
LPARAM Context)
{
UNIMPLEMENTED;
return FALSE;
return EnumNamesA(NULL, EnumFunc, Context, FALSE);
}
/*
* @unimplemented
* @implemented
*/
BOOL STDCALL
EnumWindowStationsW(WINSTAENUMPROCW lpEnumFunc,
LPARAM lParam)
EnumWindowStationsW(WINSTAENUMPROCW EnumFunc,
LPARAM Context)
{
PWCHAR Buffer;
NTSTATUS Status;
ULONG dwRequiredSize;
ULONG CurrentEntry, EntryCount;
Buffer = HeapAlloc(GetProcessHeap(), 0, 200);
if (Buffer == NULL)
{
return FALSE;
}
Status = NtUserBuildNameList(0, 200, Buffer, &dwRequiredSize);
if (Status == STATUS_BUFFER_TOO_SMALL)
{
Buffer = HeapReAlloc(GetProcessHeap(), 0, Buffer, dwRequiredSize);
if (Buffer == NULL)
{
return FALSE;
}
Status = NtUserBuildNameList(0, dwRequiredSize, Buffer, &dwRequiredSize);
}
if (Status != STATUS_SUCCESS)
{
HeapFree(GetProcessHeap(), 0, Buffer);
return FALSE;
}
EntryCount = *((DWORD *)Buffer);
Buffer += sizeof(DWORD) / sizeof(WCHAR);
for (CurrentEntry = 0; CurrentEntry < EntryCount; ++CurrentEntry)
{
(*lpEnumFunc)(Buffer, lParam);
Buffer += wcslen(Buffer) + 1;
}
return TRUE;
return EnumNamesW(NULL, EnumFunc, Context, FALSE);
}