From 43783f95c5108156d6d9a96c30f6671932143f8f Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sat, 15 May 2004 22:50:04 +0000 Subject: [PATCH] Anich Gregor: Basic implementation of GetUserObjectInformation() (needed by the nvidia opengl ICD) svn path=/trunk/; revision=9410 --- reactos/lib/user32/misc/object.c | 49 +++++++++-- reactos/subsys/win32k/ntuser/winsta.c | 115 +++++++++++++++++++++++++- 2 files changed, 154 insertions(+), 10 deletions(-) diff --git a/reactos/lib/user32/misc/object.c b/reactos/lib/user32/misc/object.c index e83d3286918..572afd56fc1 100644 --- a/reactos/lib/user32/misc/object.c +++ b/reactos/lib/user32/misc/object.c @@ -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: object.c,v 1.6 2004/01/23 23:38:26 ekohl Exp $ +/* $Id: object.c,v 1.7 2004/05/15 22:50:04 weiden Exp $ * * PROJECT: ReactOS user32.dll * FILE: lib/user32/misc/dde.c @@ -82,7 +82,7 @@ UserHandleGrantAccess( /* - * @unimplemented + * @implemented */ BOOL STDCALL @@ -93,13 +93,46 @@ GetUserObjectInformationA( DWORD nLength, LPDWORD lpnLengthNeeded) { - UNIMPLEMENTED; - return FALSE; + LPWSTR buffer; + BOOL ret = TRUE; + + DPRINT("GetUserObjectInformationA(%x %d %x %d %x)\n", hObj, nIndex, + pvInfo, nLength, lpnLengthNeeded); + + if (nIndex != UOI_NAME && nIndex != UOI_TYPE) + return GetUserObjectInformationW(hObj, nIndex, pvInfo, nLength, lpnLengthNeeded); + + /* allocate unicode buffer */ + buffer = HeapAlloc(GetProcessHeap(), 0, nLength*2); + if (buffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + + /* get unicode string */ + if (!GetUserObjectInformationW(hObj, nIndex, buffer, nLength*2, lpnLengthNeeded)) + ret = FALSE; + *lpnLengthNeeded /= 2; + + if (ret) + { + /* convert string */ + if (WideCharToMultiByte(CP_THREAD_ACP, 0, buffer, -1, + pvInfo, nLength, NULL, NULL) == 0) + { + ret = FALSE; + } + } + + /* free resources */ + HeapFree(GetProcessHeap(), 0, buffer); + return ret; } /* - * @unimplemented + * @implemented */ BOOL STDCALL @@ -110,6 +143,8 @@ GetUserObjectInformationW( DWORD nLength, LPDWORD lpnLengthNeeded) { - UNIMPLEMENTED; - return FALSE; + DPRINT("GetUserObjectInformationW(%x %d %x %d %x)\n", hObj, nIndex, + pvInfo, nLength, lpnLengthNeeded); + return NtUserGetObjectInformation(hObj, nIndex, pvInfo, nLength, lpnLengthNeeded); } + diff --git a/reactos/subsys/win32k/ntuser/winsta.c b/reactos/subsys/win32k/ntuser/winsta.c index ee852053093..383b34927c6 100644 --- a/reactos/subsys/win32k/ntuser/winsta.c +++ b/reactos/subsys/win32k/ntuser/winsta.c @@ -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: winsta.c,v 1.60 2004/05/14 23:57:32 weiden Exp $ + * $Id: winsta.c,v 1.61 2004/05/15 22:50:04 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -611,8 +611,117 @@ NtUserGetObjectInformation( DWORD nLength, PDWORD nLengthNeeded) { - SetLastNtError(STATUS_UNSUCCESSFUL); - return FALSE; + PWINSTATION_OBJECT WinStaObject = NULL; + PDESKTOP_OBJECT DesktopObject = NULL; + NTSTATUS Status; + PVOID pvData = NULL; + DWORD nDataSize = 0; + + /* try windowstation */ + DPRINT("Trying to open window station 0x%x\n", hObject); + Status = IntValidateWindowStationHandle( + hObject, + UserMode,/*ExGetPreviousMode(),*/ + GENERIC_READ, /* FIXME: is this ok? */ + &WinStaObject); + + + if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_TYPE_MISMATCH) + { + DPRINT("Failed: 0x%x\n", Status); + SetLastNtError(Status); + return FALSE; + } + + if (Status == STATUS_OBJECT_TYPE_MISMATCH) + { + /* try desktop */ + DPRINT("Trying to open desktop 0x%x\n", hObject); + Status = IntValidateDesktopHandle( + hObject, + UserMode,/*ExGetPreviousMode(),*/ + GENERIC_READ, /* FIXME: is this ok? */ + &DesktopObject); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed: 0x%x\n", Status); + SetLastNtError(Status); + return FALSE; + } + } + DPRINT("WinSta or Desktop opened!!\n"); + + /* get data */ + switch (nIndex) + { + case UOI_FLAGS: + Status = STATUS_NOT_IMPLEMENTED; + DPRINT1("UOI_FLAGS unimplemented!\n"); + break; + + case UOI_NAME: + if (WinStaObject != NULL) + { + pvData = WinStaObject->Name.Buffer; + nDataSize = WinStaObject->Name.Length+2; + Status = STATUS_SUCCESS; + } + else if (DesktopObject != NULL) + { + pvData = DesktopObject->Name.Buffer; + nDataSize = DesktopObject->Name.Length+2; + Status = STATUS_SUCCESS; + } + else + Status = STATUS_INVALID_PARAMETER; + break; + + case UOI_TYPE: + if (WinStaObject != NULL) + { + pvData = L"WindowStation"; + nDataSize = (wcslen(pvData) + 1) * sizeof(WCHAR); + Status = STATUS_SUCCESS; + } + else if (DesktopObject != NULL) + { + pvData = L"Desktop"; + nDataSize = (wcslen(pvData) + 1) * sizeof(WCHAR); + Status = STATUS_SUCCESS; + } + else + Status = STATUS_INVALID_PARAMETER; + break; + + case UOI_USER_SID: + Status = STATUS_NOT_IMPLEMENTED; + DPRINT1("UOI_USER_SID unimplemented!\n"); + break; + + default: + Status = STATUS_INVALID_PARAMETER; + break; + } + + /* try to copy data to caller */ + if (Status == STATUS_SUCCESS) + { + DPRINT("Trying to copy data to caller (len = %d, len needed = %d)\n", nLength, nDataSize); + *nLengthNeeded = nDataSize; + if (nLength >= nDataSize) + Status = MmCopyToCaller(pvInformation, pvData, nDataSize); + else + Status = STATUS_BUFFER_TOO_SMALL; + } + + /* release objects */ + if (WinStaObject != NULL) + ObDereferenceObject(WinStaObject); + if (DesktopObject != NULL) + ObDereferenceObject(DesktopObject); + + SetLastNtError(Status); + return NTSUCCESS(Status); } /*