mirror of
https://github.com/reactos/reactos.git
synced 2025-01-02 20:43:18 +00:00
Implement EnumDesktopsA/W and EnumWindowStationsA, rewrite of
EnumWindowStationsW svn path=/trunk/; revision=10637
This commit is contained in:
parent
a48867230f
commit
7f5aece68d
3 changed files with 205 additions and 56 deletions
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue