Synchronize up to trunk's revision r57756.
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 24 Nov 2012 13:02:15 +0000 (13:02 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sat, 24 Nov 2012 13:02:15 +0000 (13:02 +0000)
svn path=/branches/ros-csrss/; revision=57757

61 files changed:
1  2 
base/applications/cmdutils/doskey/doskey.c
base/services/umpnpmgr/umpnpmgr.c
base/system/diskpart/diskpart.c
base/system/services/driver.c
base/system/services/services.c
base/system/userinit/userinit.c
boot/freeldr/freeldr/windows/winldr.c
dll/win32/lsasrv/CMakeLists.txt
dll/win32/lsasrv/database.c
dll/win32/lsasrv/lsarpc.c
dll/win32/lsasrv/lsasrv.h
dll/win32/lsasrv/policy.c
dll/win32/lsasrv/security.c
dll/win32/msgina/lang/bg-BG.rc
dll/win32/msgina/lang/cs-CZ.rc
dll/win32/msgina/lang/de-DE.rc
dll/win32/msgina/lang/en-US.rc
dll/win32/msgina/lang/es-ES.rc
dll/win32/msgina/lang/fr-FR.rc
dll/win32/msgina/lang/id-ID.rc
dll/win32/msgina/lang/it-IT.rc
dll/win32/msgina/lang/ja-JP.rc
dll/win32/msgina/lang/no-NO.rc
dll/win32/msgina/lang/pl-PL.rc
dll/win32/msgina/lang/ro-RO.rc
dll/win32/msgina/lang/ru-RU.rc
dll/win32/msgina/lang/sk-SK.rc
dll/win32/msgina/lang/uk-UA.rc
dll/win32/msgina/msgina.c
dll/win32/msgina/resources/reactos.bmp
dll/win32/netapi32/local_group.c
dll/win32/syssetup/install.c
include/psdk/ntlsa.h
include/psdk/winerror.h
lib/sdk/crt/stdio/file.c
media/vgafonts/CMakeLists.txt
ntoskrnl/config/cmsysini.c
win32ss/gdi/eng/mouse.c
win32ss/gdi/eng/mouse.h
win32ss/gdi/eng/pdevobj.h
win32ss/gdi/ntgdi/dc.h
win32ss/gdi/ntgdi/dcutil.c
win32ss/gdi/ntgdi/dib.h
win32ss/gdi/ntgdi/dibobj.c
win32ss/include/ntuser.h
win32ss/user/consrv/console.c
win32ss/user/ntuser/clipboard.c
win32ss/user/ntuser/cursoricon.c
win32ss/user/ntuser/cursoricon.h
win32ss/user/ntuser/cursoricon_new.c
win32ss/user/ntuser/display.c
win32ss/user/ntuser/keyboard.c
win32ss/user/ntuser/message.c
win32ss/user/ntuser/misc/file.c
win32ss/user/ntuser/msgqueue.c
win32ss/user/ntuser/msgqueue.h
win32ss/user/ntuser/timer.c
win32ss/user/ntuser/windc.c
win32ss/user/user32/misc/misc.c
win32ss/user/user32/windows/cursoricon_new.c
win32ss/w32ksvc.h

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000,7112470..7112470
mode 000000,100644..100644
--- /dev/null
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index b5775ae,7fd0563..7fd0563
Binary files differ
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index e403429,0000000..ee4d57c
mode 100644,000000..100644
--- /dev/null
@@@ -1,904 -1,0 +1,920 @@@
-             DPRINT1("Failed to open text-mode console, switching to gui-mode\n");
 +/*
 + * COPYRIGHT:       See COPYING in the top level directory
 + * PROJECT:         ReactOS Console Server DLL
 + * FILE:            win32ss/user/consrv/console.c
 + * PURPOSE:         Console I/O functions
 + * PROGRAMMERS:
 + */
 +
 +/* INCLUDES ******************************************************************/
 +
 +#include "consrv.h"
 +#include "guiconsole.h"
 +#include "tuiconsole.h"
 +
 +#define NDEBUG
 +#include <debug.h>
 +
 +/* FUNCTIONS *****************************************************************/
 +
 +BOOL FASTCALL
 +DtbgIsDesktopVisible(VOID)
 +{
 +    HWND VisibleDesktopWindow = GetDesktopWindow(); // DESKTOPWNDPROC
 +
 +    if (VisibleDesktopWindow != NULL &&
 +            !IsWindowVisible(VisibleDesktopWindow))
 +    {
 +        VisibleDesktopWindow = NULL;
 +    }
 +
 +    return VisibleDesktopWindow != NULL;
 +}
 +
 +NTSTATUS FASTCALL
 +ConioConsoleFromProcessData(PCONSOLE_PROCESS_DATA ProcessData,
 +                            PCSRSS_CONSOLE *Console)
 +{
 +    PCSRSS_CONSOLE ProcessConsole;
 +
 +    RtlEnterCriticalSection(&ProcessData->HandleTableLock);
 +    ProcessConsole = ProcessData->Console;
 +
 +    if (!ProcessConsole)
 +    {
 +        *Console = NULL;
 +        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +        return STATUS_INVALID_HANDLE;
 +    }
 +
 +    InterlockedIncrement(&ProcessConsole->ReferenceCount);
 +    RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +    EnterCriticalSection(&(ProcessConsole->Lock));
 +    *Console = ProcessConsole;
 +
 +    return STATUS_SUCCESS;
 +}
 +
 +VOID FASTCALL
 +ConioConsoleCtrlEventTimeout(DWORD Event,
 +                             PCONSOLE_PROCESS_DATA ProcessData,
 +                             DWORD Timeout)
 +{
 +    HANDLE Thread;
 +
 +    DPRINT("ConioConsoleCtrlEvent Parent ProcessId = %x\n", ProcessData->Process->ClientId.UniqueProcess);
 +
 +    if (ProcessData->CtrlDispatcher)
 +    {
 +        Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
 +                                    ProcessData->CtrlDispatcher,
 +                                    UlongToPtr(Event), 0, NULL);
 +        if (NULL == Thread)
 +        {
 +            DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
 +            return;
 +        }
 +
 +        WaitForSingleObject(Thread, Timeout);
 +        CloseHandle(Thread);
 +    }
 +}
 +
 +VOID FASTCALL
 +ConioConsoleCtrlEvent(DWORD Event, PCONSOLE_PROCESS_DATA ProcessData)
 +{
 +    ConioConsoleCtrlEventTimeout(Event, ProcessData, 0);
 +}
 +
 +static NTSTATUS WINAPI
 +CsrInitConsole(PCSRSS_CONSOLE Console, int ShowCmd)
 +{
 +    NTSTATUS Status;
 +    SECURITY_ATTRIBUTES SecurityAttributes;
 +    PCSRSS_SCREEN_BUFFER NewBuffer;
 +    BOOL GuiMode;
 +    WCHAR Title[255];
 +
 +    Console->Title.MaximumLength = Console->Title.Length = 0;
 +    Console->Title.Buffer = NULL;
 +
 +    if (LoadStringW(ConSrvDllInstance, IDS_COMMAND_PROMPT, Title, sizeof(Title) / sizeof(Title[0])))
 +    {
 +        RtlCreateUnicodeString(&Console->Title, Title);
 +    }
 +    else
 +    {
 +        RtlCreateUnicodeString(&Console->Title, L"Command Prompt");
 +    }
 +
 +    Console->ReferenceCount = 0;
 +    Console->LineBuffer = NULL;
 +    Console->Header.Type = CONIO_CONSOLE_MAGIC;
 +    Console->Header.Console = Console;
 +    Console->Mode = ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT;
 +    InitializeListHead(&Console->BufferList);
 +    Console->ActiveBuffer = NULL;
 +    InitializeListHead(&Console->InputEvents);
 +    InitializeListHead(&Console->HistoryBuffers);
 +    Console->CodePage = GetOEMCP();
 +    Console->OutputCodePage = GetOEMCP();
 +
 +    SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
 +    SecurityAttributes.lpSecurityDescriptor = NULL;
 +    SecurityAttributes.bInheritHandle = TRUE;
 +
 +    Console->ActiveEvent = CreateEventW(&SecurityAttributes, TRUE, FALSE, NULL);
 +    if (NULL == Console->ActiveEvent)
 +    {
 +        RtlFreeUnicodeString(&Console->Title);
 +        return STATUS_UNSUCCESSFUL;
 +    }
 +    Console->PrivateData = NULL;
 +    InitializeCriticalSection(&Console->Lock);
 +
 +    GuiMode = DtbgIsDesktopVisible();
 +
 +    /* allocate console screen buffer */
 +    NewBuffer = HeapAlloc(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_SCREEN_BUFFER));
 +    if (NULL == NewBuffer)
 +    {
 +        RtlFreeUnicodeString(&Console->Title);
 +        DeleteCriticalSection(&Console->Lock);
 +        CloseHandle(Console->ActiveEvent);
 +        return STATUS_INSUFFICIENT_RESOURCES;
 +    }
 +    /* init screen buffer with defaults */
 +    NewBuffer->CursorInfo.bVisible = TRUE;
 +    NewBuffer->CursorInfo.dwSize = CSR_DEFAULT_CURSOR_SIZE;
 +    /* make console active, and insert into console list */
 +    Console->ActiveBuffer = (PCSRSS_SCREEN_BUFFER) NewBuffer;
 +
++    /*
++     * If we are not in GUI-mode, start the text-mode console. If we fail,
++     * try to start the GUI-mode console (win32k will automatically switch
++     * to graphical mode, therefore no additional code is needed).
++     */
 +    if (!GuiMode)
 +    {
++        DPRINT1("WIN32CSR: Opening text-mode console\n");
 +        Status = TuiInitConsole(Console);
 +        if (!NT_SUCCESS(Status))
 +        {
-     else /* GuiMode */
++            DPRINT1("Failed to open text-mode console, switching to gui-mode, Status = 0x%08lx\n", Status);
 +            GuiMode = TRUE;
 +        }
 +    }
-             DPRINT1("GuiInitConsole: failed\n");
++
++    /*
++     * Try to open the GUI-mode console. Two cases are possible:
++     * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
++     *   failed and we start GUI-mode console.
++     * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
++     *   succeeded BUT we failed at starting text-mode console. Then GuiMode
++     *   was switched to TRUE in order to try to open the console in GUI-mode.
++     */
++    if (GuiMode)
 +    {
++        DPRINT1("WIN32CSR: Opening GUI-mode console\n");
 +        Status = GuiInitConsole(Console, ShowCmd);
 +        if (!NT_SUCCESS(Status))
 +        {
 +            HeapFree(ConSrvHeap,0, NewBuffer);
 +            RtlFreeUnicodeString(&Console->Title);
 +            DeleteCriticalSection(&Console->Lock);
 +            CloseHandle(Console->ActiveEvent);
-     if (! NT_SUCCESS(Status))
++            DPRINT1("GuiInitConsole: failed, Status = 0x%08lx\n", Status);
 +            return Status;
 +        }
 +    }
 +
 +    Status = CsrInitConsoleScreenBuffer(Console, NewBuffer);
++    if (!NT_SUCCESS(Status))
 +    {
 +        ConioCleanupConsole(Console);
 +        RtlFreeUnicodeString(&Console->Title);
 +        DeleteCriticalSection(&Console->Lock);
 +        CloseHandle(Console->ActiveEvent);
 +        HeapFree(ConSrvHeap, 0, NewBuffer);
 +        DPRINT1("CsrInitConsoleScreenBuffer: failed\n");
 +        return Status;
 +    }
 +
 +    /* copy buffer contents to screen */
 +    ConioDrawConsole(Console);
 +
 +    return STATUS_SUCCESS;
 +}
 +
 +CSR_API(SrvOpenConsole)
 +{
 +    NTSTATUS Status = STATUS_SUCCESS;
 +    PCSRSS_OPEN_CONSOLE OpenConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.OpenConsoleRequest;
 +    PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
 +
 +    DPRINT("SrvOpenConsole\n");
 +
 +    OpenConsoleRequest->Handle = INVALID_HANDLE_VALUE;
 +
 +    RtlEnterCriticalSection(&ProcessData->HandleTableLock);
 +
 +    DPRINT1("SrvOpenConsole - Checkpoint 1\n");
 +    DPRINT1("ProcessData = 0x%p ; ProcessData->Console = 0x%p\n", ProcessData, ProcessData->Console);
 +
 +    if (ProcessData->Console)
 +    {
 +        DWORD DesiredAccess = OpenConsoleRequest->Access;
 +        DWORD ShareMode = OpenConsoleRequest->ShareMode;
 +
 +        PCSRSS_CONSOLE Console = ProcessData->Console;
 +        Object_t *Object;
 +
 +        DPRINT1("SrvOpenConsole - Checkpoint 2\n");
 +        EnterCriticalSection(&Console->Lock);
 +        DPRINT1("SrvOpenConsole - Checkpoint 3\n");
 +
 +        if (OpenConsoleRequest->HandleType == HANDLE_OUTPUT)
 +            Object = &Console->ActiveBuffer->Header;
 +        else // HANDLE_INPUT
 +            Object = &Console->Header;
 +
 +        if (((DesiredAccess & GENERIC_READ)  && Object->ExclusiveRead  != 0) ||
 +            ((DesiredAccess & GENERIC_WRITE) && Object->ExclusiveWrite != 0) ||
 +            (!(ShareMode & FILE_SHARE_READ)  && Object->AccessRead     != 0) ||
 +            (!(ShareMode & FILE_SHARE_WRITE) && Object->AccessWrite    != 0))
 +        {
 +            DPRINT1("Sharing violation\n");
 +            Status = STATUS_SHARING_VIOLATION;
 +        }
 +        else
 +        {
 +            Status = Win32CsrInsertObject(ProcessData,
 +                                          &OpenConsoleRequest->Handle,
 +                                          Object,
 +                                          DesiredAccess,
 +                                          OpenConsoleRequest->Inheritable,
 +                                          ShareMode);
 +        }
 +
 +        LeaveCriticalSection(&Console->Lock);
 +    }
 +
 +    RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +
 +    return Status;
 +}
 +
 +CSR_API(SrvAllocConsole)
 +{
 +    NTSTATUS Status = STATUS_SUCCESS;
 +    PCSRSS_ALLOC_CONSOLE AllocConsoleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.AllocConsoleRequest;
 +    PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
 +    PCSRSS_CONSOLE Console;
 +    BOOLEAN NewConsole = FALSE;
 +
 +    DPRINT("SrvAllocConsole\n");
 +
 +    RtlEnterCriticalSection(&ProcessData->HandleTableLock);
 +
 +    if (ProcessData->Console)
 +    {
 +        DPRINT1("Process already has a console\n");
 +        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +        return STATUS_INVALID_PARAMETER;
 +    }
 +
 +    DPRINT1("SrvAllocConsole - Checkpoint 1\n");
 +
 +    /* If we don't need a console, then get out of here */
 +    if (!AllocConsoleRequest->ConsoleNeeded)
 +    {
 +        DPRINT("No console needed\n");
 +        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +        return STATUS_SUCCESS;
 +    }
 +
 +    /* If we already have one, then don't create a new one... */
 +    if (!AllocConsoleRequest->Console ||
 +         AllocConsoleRequest->Console != ProcessData->ParentConsole)
 +    {
 +        /* Allocate a console structure */
 +        NewConsole = TRUE;
 +        Console = HeapAlloc(ConSrvHeap, HEAP_ZERO_MEMORY, sizeof(CSRSS_CONSOLE));
 +        if (NULL == Console)
 +        {
 +            DPRINT1("Not enough memory for console\n");
 +            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +            return STATUS_NO_MEMORY;
 +        }
 +
 +        /* Initialize list head */
 +        InitializeListHead(&Console->ProcessList);
 +
 +        /* Insert process data required for GUI initialization */
 +        InsertHeadList(&Console->ProcessList, &ProcessData->ConsoleLink);
 +
 +        /* Initialize the Console */
 +        Status = CsrInitConsole(Console, AllocConsoleRequest->ShowCmd);
 +        if (!NT_SUCCESS(Status))
 +        {
 +            DPRINT1("Console init failed\n");
 +            HeapFree(ConSrvHeap, 0, Console);
 +            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +            return Status;
 +        }
 +    }
 +    else
 +    {
 +        /* Reuse our current console */
 +        Console = AllocConsoleRequest->Console;
 +    }
 +
 +    /* Set the Process Console */
 +    ProcessData->Console = Console;
 +
 +    /* Return it to the caller */
 +    AllocConsoleRequest->Console = Console;
 +
 +    /* Add a reference count because the process is tied to the console */
 +    _InterlockedIncrement(&Console->ReferenceCount);
 +
 +    if (NewConsole || !ProcessData->bInheritHandles)
 +    {
 +        /* Insert the Objects */
 +        Status = Win32CsrInsertObject(ProcessData,
 +                                      &AllocConsoleRequest->InputHandle,
 +                                      &Console->Header,
 +                                      GENERIC_READ | GENERIC_WRITE,
 +                                      TRUE,
 +                                      FILE_SHARE_READ | FILE_SHARE_WRITE);
 +        if (! NT_SUCCESS(Status))
 +        {
 +            DPRINT1("Failed to insert object\n");
 +            ConioDeleteConsole((Object_t *) Console);
 +            ProcessData->Console = NULL;
 +            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +            return Status;
 +        }
 +
 +        Status = Win32CsrInsertObject(ProcessData,
 +                                      &AllocConsoleRequest->OutputHandle,
 +                                      &Console->ActiveBuffer->Header,
 +                                      GENERIC_READ | GENERIC_WRITE,
 +                                      TRUE,
 +                                      FILE_SHARE_READ | FILE_SHARE_WRITE);
 +        if (!NT_SUCCESS(Status))
 +        {
 +            DPRINT1("Failed to insert object\n");
 +            ConioDeleteConsole((Object_t *) Console);
 +            Win32CsrReleaseObject(ProcessData,
 +                                  AllocConsoleRequest->InputHandle);
 +            ProcessData->Console = NULL;
 +            RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +            return Status;
 +        }
 +    }
 +
 +    /* Duplicate the Event */
 +    Status = NtDuplicateObject(NtCurrentProcess(),
 +                               ProcessData->Console->ActiveEvent,
 +                               ProcessData->Process->ProcessHandle,
 +                               &ProcessData->ConsoleEvent,
 +                               EVENT_ALL_ACCESS, 0, 0);
 +    if (!NT_SUCCESS(Status))
 +    {
 +        DPRINT1("NtDuplicateObject() failed: %lu\n", Status);
 +        ConioDeleteConsole((Object_t *) Console);
 +        if (NewConsole || !ProcessData->bInheritHandles)
 +        {
 +            Win32CsrReleaseObject(ProcessData,
 +                                  AllocConsoleRequest->OutputHandle);
 +            Win32CsrReleaseObject(ProcessData,
 +                                  AllocConsoleRequest->InputHandle);
 +        }
 +        ProcessData->Console = NULL;
 +        RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +        return Status;
 +    }
 +
 +    /* Set the Ctrl Dispatcher */
 +    ProcessData->CtrlDispatcher = AllocConsoleRequest->CtrlDispatcher;
 +    DPRINT("CSRSS:CtrlDispatcher address: %x\n", ProcessData->CtrlDispatcher);
 +
 +    if (!NewConsole)
 +    {
 +        /* Insert into the list if it has not been added */
 +        InsertHeadList(&ProcessData->Console->ProcessList, &ProcessData->ConsoleLink);
 +    }
 +
 +    RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
 +    return STATUS_SUCCESS;
 +}
 +
 +CSR_API(SrvFreeConsole)
 +{
 +    Win32CsrReleaseConsole(CsrGetClientThread()->Process);
 +    return STATUS_SUCCESS;
 +}
 +
 +VOID WINAPI
 +ConioDeleteConsole(Object_t *Object)
 +{
 +    PCSRSS_CONSOLE Console = (PCSRSS_CONSOLE) Object;
 +    ConsoleInput *Event;
 +
 +    DPRINT("ConioDeleteConsole\n");
 +
 +    /* Drain input event queue */
 +    while (Console->InputEvents.Flink != &Console->InputEvents)
 +    {
 +        Event = (ConsoleInput *) Console->InputEvents.Flink;
 +        Console->InputEvents.Flink = Console->InputEvents.Flink->Flink;
 +        Console->InputEvents.Flink->Flink->Blink = &Console->InputEvents;
 +        HeapFree(ConSrvHeap, 0, Event);
 +    }
 +
 +    ConioCleanupConsole(Console);
 +    if (Console->LineBuffer)
 +        RtlFreeHeap(ConSrvHeap, 0, Console->LineBuffer);
 +    while (!IsListEmpty(&Console->HistoryBuffers))
 +        HistoryDeleteBuffer((struct tagHISTORY_BUFFER *)Console->HistoryBuffers.Flink);
 +
 +    ConioDeleteScreenBuffer(Console->ActiveBuffer);
 +    if (!IsListEmpty(&Console->BufferList))
 +    {
 +        DPRINT1("BUG: screen buffer list not empty\n");
 +    }
 +
 +    CloseHandle(Console->ActiveEvent);
 +    if (Console->UnpauseEvent) CloseHandle(Console->UnpauseEvent);
 +    DeleteCriticalSection(&Console->Lock);
 +    RtlFreeUnicodeString(&Console->Title);
 +    IntDeleteAllAliases(Console->Aliases);
 +    HeapFree(ConSrvHeap, 0, Console);
 +}
 +
 +VOID WINAPI
 +CsrInitConsoleSupport(VOID)
 +{
 +    DPRINT("CSR: CsrInitConsoleSupport()\n");
 +
 +    /* Should call LoadKeyboardLayout */
 +}
 +
 +VOID FASTCALL
 +ConioPause(PCSRSS_CONSOLE Console, UINT Flags)
 +{
 +    Console->PauseFlags |= Flags;
 +    if (!Console->UnpauseEvent)
 +        Console->UnpauseEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 +}
 +
 +VOID FASTCALL
 +ConioUnpause(PCSRSS_CONSOLE Console, UINT Flags)
 +{
 +    Console->PauseFlags &= ~Flags;
 +    if (Console->PauseFlags == 0 && Console->UnpauseEvent)
 +    {
 +        SetEvent(Console->UnpauseEvent);
 +        CloseHandle(Console->UnpauseEvent);
 +        Console->UnpauseEvent = NULL;
 +    }
 +}
 +
 +CSR_API(SrvSetConsoleMode)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_CONSOLE_MODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
 +    PCSRSS_CONSOLE Console;
 +    PCSRSS_SCREEN_BUFFER Buff;
 +
 +    DPRINT("SrvSetConsoleMode\n");
 +
 +    Status = Win32CsrLockObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
 +                                ConsoleModeRequest->ConsoleHandle,
 +                                (Object_t **) &Console, GENERIC_WRITE, 0);
 +    if (!NT_SUCCESS(Status)) return Status;
 +
 +    Buff = (PCSRSS_SCREEN_BUFFER)Console;
 +
 +    if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
 +    {
 +        Console->Mode = ConsoleModeRequest->ConsoleMode & CONSOLE_INPUT_MODE_VALID;
 +    }
 +    else if (CONIO_SCREEN_BUFFER_MAGIC == Console->Header.Type)
 +    {
 +        Buff->Mode = ConsoleModeRequest->ConsoleMode & CONSOLE_OUTPUT_MODE_VALID;
 +    }
 +    else
 +    {
 +        Status = STATUS_INVALID_HANDLE;
 +    }
 +
 +    Win32CsrUnlockObject((Object_t *)Console);
 +
 +    return Status;
 +}
 +
 +CSR_API(SrvGetConsoleMode)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_CONSOLE_MODE ConsoleModeRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleModeRequest;
 +    PCSRSS_CONSOLE Console;
 +    PCSRSS_SCREEN_BUFFER Buff;
 +
 +    DPRINT("SrvGetConsoleMode\n");
 +
 +    Status = Win32CsrLockObject(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
 +                                ConsoleModeRequest->ConsoleHandle,
 +                                (Object_t **) &Console, GENERIC_READ, 0);
 +    if (!NT_SUCCESS(Status)) return Status;
 +
 +    Status = STATUS_SUCCESS;
 +    Buff = (PCSRSS_SCREEN_BUFFER) Console;
 +
 +    if (CONIO_CONSOLE_MAGIC == Console->Header.Type)
 +    {
 +        ConsoleModeRequest->ConsoleMode = Console->Mode;
 +    }
 +    else if (CONIO_SCREEN_BUFFER_MAGIC == Buff->Header.Type)
 +    {
 +        ConsoleModeRequest->ConsoleMode = Buff->Mode;
 +    }
 +    else
 +    {
 +        Status = STATUS_INVALID_HANDLE;
 +    }
 +
 +    Win32CsrUnlockObject((Object_t *)Console);
 +    return Status;
 +}
 +
 +CSR_API(SrvSetConsoleTitle)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_CONSOLE_TITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
 +    // PCSR_PROCESS Process = CsrGetClientThread()->Process;
 +    PCSRSS_CONSOLE Console;
 +    PWCHAR Buffer;
 +
 +    DPRINT("SrvSetConsoleTitle\n");
 +
 +    if (!CsrValidateMessageBuffer(ApiMessage,
 +                                  (PVOID)&TitleRequest->Title,
 +                                  TitleRequest->Length,
 +                                  sizeof(BYTE)))
 +    {
 +        return STATUS_INVALID_PARAMETER;
 +    }
 +/*
 +    if (!Win32CsrValidateBuffer(Process, TitleRequest->Title,
 +                                TitleRequest->Length, 1))
 +    {
 +        return STATUS_ACCESS_VIOLATION;
 +    }
 +*/
 +
 +    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
 +    if(NT_SUCCESS(Status))
 +    {
 +        Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, TitleRequest->Length);
 +        if (Buffer)
 +        {
 +            /* Copy title to console */
 +            RtlFreeUnicodeString(&Console->Title);
 +            Console->Title.Buffer = Buffer;
 +            Console->Title.Length = Console->Title.MaximumLength = TitleRequest->Length;
 +            memcpy(Console->Title.Buffer, TitleRequest->Title, Console->Title.Length);
 +
 +            if (!ConioChangeTitle(Console))
 +            {
 +                Status = STATUS_UNSUCCESSFUL;
 +            }
 +            else
 +            {
 +                Status = STATUS_SUCCESS;
 +            }
 +        }
 +        else
 +        {
 +            Status = STATUS_NO_MEMORY;
 +        }
 +
 +        ConioUnlockConsole(Console);
 +    }
 +
 +    return Status;
 +}
 +
 +CSR_API(SrvGetConsoleTitle)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_CONSOLE_TITLE TitleRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.TitleRequest;
 +    // PCSR_PROCESS Process = CsrGetClientThread()->Process;
 +    PCSRSS_CONSOLE Console;
 +    DWORD Length;
 +
 +    DPRINT("SrvGetConsoleTitle\n");
 +
 +    if (!CsrValidateMessageBuffer(ApiMessage,
 +                                  (PVOID)&TitleRequest->Title,
 +                                  TitleRequest->Length,
 +                                  sizeof(BYTE)))
 +    {
 +        return STATUS_INVALID_PARAMETER;
 +    }
 +/*
 +    if (!Win32CsrValidateBuffer(Process, TitleRequest->Title,
 +                                TitleRequest->Length, 1))
 +    {
 +        return STATUS_ACCESS_VIOLATION;
 +    }
 +*/
 +
 +    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
 +    if (!NT_SUCCESS(Status))
 +    {
 +        DPRINT1("Can't get console\n");
 +        return Status;
 +    }
 +
 +    /* Copy title of the console to the user title buffer */
 +    if (TitleRequest->Length >= sizeof(WCHAR))
 +    {
 +        Length = min(TitleRequest->Length - sizeof(WCHAR), Console->Title.Length);
 +        memcpy(TitleRequest->Title, Console->Title.Buffer, Length);
 +        TitleRequest->Title[Length / sizeof(WCHAR)] = L'\0';
 +    }
 +
 +    TitleRequest->Length = Console->Title.Length;
 +
 +    ConioUnlockConsole(Console);
 +    return STATUS_SUCCESS;
 +}
 +
 +/**********************************************************************
 + *  HardwareStateProperty
 + *
 + *  DESCRIPTION
 + *      Set/Get the value of the HardwareState and switch
 + *      between direct video buffer ouput and GDI windowed
 + *      output.
 + *  ARGUMENTS
 + *      Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
 + *      object. We use the same object to Request.
 + *  NOTE
 + *      ConsoleHwState has the correct size to be compatible
 + *      with NT's, but values are not.
 + */
 +static NTSTATUS FASTCALL
 +SetConsoleHardwareState(PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
 +{
 +    DPRINT1("Console Hardware State: %d\n", ConsoleHwState);
 +
 +    if ((CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
 +            ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState))
 +    {
 +        if (Console->HardwareState != ConsoleHwState)
 +        {
 +            /* TODO: implement switching from full screen to windowed mode */
 +            /* TODO: or back; now simply store the hardware state */
 +            Console->HardwareState = ConsoleHwState;
 +        }
 +
 +        return STATUS_SUCCESS;
 +    }
 +
 +    return STATUS_INVALID_PARAMETER_3; /* Client: (handle, set_get, [mode]) */
 +}
 +
 +CSR_API(SrvGetConsoleHardwareState)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleHardwareStateRequest;
 +    PCSRSS_CONSOLE Console;
 +
 +    DPRINT("SrvGetConsoleHardwareState\n");
 +
 +    Status = ConioLockConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
 +                              ConsoleHardwareStateRequest->ConsoleHandle,
 +                              &Console,
 +                              GENERIC_READ);
 +    if (!NT_SUCCESS(Status))
 +    {
 +        DPRINT1("Failed to get console handle in SrvGetConsoleHardwareState\n");
 +        return Status;
 +    }
 +
 +    ConsoleHardwareStateRequest->State = Console->HardwareState;
 +
 +    ConioUnlockConsole(Console);
 +
 +    return Status;
 +}
 +
 +CSR_API(SrvSetConsoleHardwareState)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleHardwareStateRequest;
 +    PCSRSS_CONSOLE Console;
 +
 +    DPRINT("SrvSetConsoleHardwareState\n");
 +
 +    Status = ConioLockConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process),
 +                              ConsoleHardwareStateRequest->ConsoleHandle,
 +                              &Console,
 +                              GENERIC_READ);
 +    if (!NT_SUCCESS(Status))
 +    {
 +        DPRINT1("Failed to get console handle in SrvSetConsoleHardwareState\n");
 +        return Status;
 +    }
 +
 +    DPRINT("Setting console hardware state.\n");
 +    Status = SetConsoleHardwareState(Console, ConsoleHardwareStateRequest->State);
 +
 +    ConioUnlockConsole(Console);
 +
 +    return Status;
 +}
 +
 +CSR_API(SrvGetConsoleWindow)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_GET_CONSOLE_WINDOW GetConsoleWindowRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetConsoleWindowRequest;
 +    PCSRSS_CONSOLE Console;
 +
 +    DPRINT("SrvGetConsoleWindow\n");
 +
 +    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
 +    if (!NT_SUCCESS(Status)) return Status;
 +
 +    GetConsoleWindowRequest->WindowHandle = Console->hWindow;
 +    ConioUnlockConsole(Console);
 +
 +    return STATUS_SUCCESS;
 +}
 +
 +CSR_API(SrvSetConsoleIcon)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_SET_CONSOLE_ICON SetConsoleIconRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetConsoleIconRequest;
 +    PCSRSS_CONSOLE Console;
 +
 +    DPRINT("SrvSetConsoleIcon\n");
 +
 +    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
 +    if (!NT_SUCCESS(Status)) return Status;
 +
 +    Status = (ConioChangeIcon(Console, SetConsoleIconRequest->WindowIcon)
 +                ? STATUS_SUCCESS
 +                : STATUS_UNSUCCESSFUL);
 +
 +    ConioUnlockConsole(Console);
 +
 +    return Status;
 +}
 +
 +CSR_API(SrvGetConsoleCP)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_CONSOLE_CP ConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleCPRequest;
 +    PCSRSS_CONSOLE Console;
 +
 +    DPRINT("SrvGetConsoleCP, getting %s Code Page\n",
 +            ConsoleCPRequest->InputCP ? "Input" : "Output");
 +
 +    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
 +    if (!NT_SUCCESS(Status)) return Status;
 +
 +    ConsoleCPRequest->CodePage = (ConsoleCPRequest->InputCP ? Console->CodePage
 +                                                            : Console->OutputCodePage);
 +    ConioUnlockConsole(Console);
 +    return STATUS_SUCCESS;
 +}
 +
 +CSR_API(SrvSetConsoleCP)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_CONSOLE_CP ConsoleCPRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.ConsoleCPRequest;
 +    PCSRSS_CONSOLE Console;
 +
 +    DPRINT("SrvSetConsoleCP, setting %s Code Page\n",
 +            ConsoleCPRequest->InputCP ? "Input" : "Output");
 +
 +    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
 +    if (!NT_SUCCESS(Status)) return Status;
 +
 +    if (IsValidCodePage(ConsoleCPRequest->CodePage))
 +    {
 +        if (ConsoleCPRequest->InputCP)
 +            Console->CodePage = ConsoleCPRequest->CodePage;
 +        else
 +            Console->OutputCodePage = ConsoleCPRequest->CodePage;
 +
 +        ConioUnlockConsole(Console);
 +        return STATUS_SUCCESS;
 +    }
 +
 +    ConioUnlockConsole(Console);
 +    return STATUS_INVALID_PARAMETER;
 +}
 +
 +CSR_API(SrvGetConsoleProcessList)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_GET_PROCESS_LIST GetProcessListRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetProcessListRequest;
 +    PDWORD Buffer;
 +    // PCSR_PROCESS Process = CsrGetClientThread()->Process;
 +    PCSRSS_CONSOLE Console;
 +    PCONSOLE_PROCESS_DATA current;
 +    PLIST_ENTRY current_entry;
 +    ULONG nItems = 0;
 +
 +    DPRINT("SrvGetConsoleProcessList\n");
 +
 +    if (!CsrValidateMessageBuffer(ApiMessage,
 +                                  (PVOID)&GetProcessListRequest->pProcessIds,
 +                                  GetProcessListRequest->nMaxIds,
 +                                  sizeof(DWORD)))
 +    {
 +        return STATUS_INVALID_PARAMETER;
 +    }
 +
 +    Buffer = GetProcessListRequest->pProcessIds;
 +
 +/*
 +    if (!Win32CsrValidateBuffer(ProcessData, Buffer, GetProcessListRequest->nMaxIds, sizeof(DWORD)))
 +        return STATUS_ACCESS_VIOLATION;
 +*/
 +
 +    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
 +    if (!NT_SUCCESS(Status)) return Status;
 +
 +    for (current_entry = Console->ProcessList.Flink;
 +         current_entry != &Console->ProcessList;
 +         current_entry = current_entry->Flink)
 +    {
 +        current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
 +        if (++nItems <= GetProcessListRequest->nMaxIds)
 +        {
 +            *Buffer++ = HandleToUlong(current->Process->ClientId.UniqueProcess);
 +        }
 +    }
 +
 +    ConioUnlockConsole(Console);
 +
 +    GetProcessListRequest->nProcessIdsTotal = nItems;
 +    return STATUS_SUCCESS;
 +}
 +
 +CSR_API(SrvGenerateConsoleCtrlEvent)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_GENERATE_CTRL_EVENT GenerateCtrlEvent = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GenerateCtrlEvent;
 +    PCSRSS_CONSOLE Console;
 +    PCONSOLE_PROCESS_DATA current;
 +    PLIST_ENTRY current_entry;
 +    DWORD Group;
 +
 +    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
 +    if (!NT_SUCCESS(Status)) return Status;
 +
 +    Group = GenerateCtrlEvent->ProcessGroup;
 +    Status = STATUS_INVALID_PARAMETER;
 +    for (current_entry  = Console->ProcessList.Flink;
 +         current_entry != &Console->ProcessList;
 +         current_entry  = current_entry->Flink)
 +    {
 +        current = CONTAINING_RECORD(current_entry, CONSOLE_PROCESS_DATA, ConsoleLink);
 +        if (Group == 0 || current->Process->ProcessGroupId == Group)
 +        {
 +            ConioConsoleCtrlEvent(GenerateCtrlEvent->Event, current);
 +            Status = STATUS_SUCCESS;
 +        }
 +    }
 +
 +    ConioUnlockConsole(Console);
 +
 +    return Status;
 +}
 +
 +CSR_API(SrvGetConsoleSelectionInfo)
 +{
 +    NTSTATUS Status;
 +    PCSRSS_GET_CONSOLE_SELECTION_INFO GetConsoleSelectionInfo = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetConsoleSelectionInfo;
 +    PCSRSS_CONSOLE Console;
 +
 +    Status = ConioConsoleFromProcessData(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console);
 +    if (NT_SUCCESS(Status))
 +    {
 +        memset(&GetConsoleSelectionInfo->Info, 0, sizeof(CONSOLE_SELECTION_INFO));
 +        if (Console->Selection.dwFlags != 0)
 +            GetConsoleSelectionInfo->Info = Console->Selection;
 +        ConioUnlockConsole(Console);
 +    }
 +
 +    return Status;
 +}
 +
 +/* EOF */
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index d211bb1,0000000..a473e79
mode 100644,000000..100644
--- /dev/null
@@@ -1,595 -1,0 +1,590 @@@
-     PWND Wnd;
 +/*
 + *  ReactOS kernel
 + *  Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
 + *
 + *  This program is free software; you can redistribute it and/or modify
 + *  it under the terms of the GNU General Public License as published by
 + *  the Free Software Foundation; either version 2 of the License, or
 + *  (at your option) any later version.
 + *
 + *  This program is distributed in the hope that it will be useful,
 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + *  GNU General Public License for more details.
 + *
 + *  You should have received a copy of the GNU General Public License
 + *  along with this program; if not, write to the Free Software
 + *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 + */
 +/*
 + * PROJECT:         ReactOS user32.dll
 + * FILE:            lib/user32/misc/misc.c
 + * PURPOSE:         Misc
 + * PROGRAMMER:      Thomas Weidenmueller (w3seek@users.sourceforge.net)
 + * UPDATE HISTORY:
 + *      19-11-2003  Created
 + */
 +
 +/* INCLUDES ******************************************************************/
 +
 +#include <user32.h>
 +
 +#include <wine/debug.h>
 +
 +WINE_DEFAULT_DEBUG_CHANNEL(user32);
 +
 +/* FUNCTIONS *****************************************************************/
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +RegisterLogonProcess(DWORD dwProcessId, BOOL bRegister)
 +{
 +    gfLogonProcess = NtUserxRegisterLogonProcess(dwProcessId, bRegister);
 +
 +    if (gfLogonProcess)
 +    {
 +        NTSTATUS Status;
 +        USER_API_MESSAGE ApiMessage;
 +
 +        ApiMessage.Data.RegisterLogonProcessRequest.ProcessId = dwProcessId;
 +        ApiMessage.Data.RegisterLogonProcessRequest.Register = bRegister;
 +
 +        Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
 +                                     NULL,
 +                                     CSR_CREATE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpRegisterLogonProcess),
 +                                     sizeof(CSRSS_REGISTER_LOGON_PROCESS));
 +        if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
 +        {
 +            SetLastError(RtlNtStatusToDosError(Status));
 +            ERR("Failed to register logon process with CSRSS\n");
 +            // return FALSE;
 +        }
 +    }
 +
 +    return gfLogonProcess;
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +SetLogonNotifyWindow(HWND Wnd, HWINSTA WinSta)
 +{
 +/// HACK: Windows does not do this !! ReactOS-specific
 +    /* Maybe we should call NtUserSetLogonNotifyWindow and let that one inform CSRSS??? */
 +    USER_API_MESSAGE Request;
 +    NTSTATUS Status;
 +
 +    Request.Data.SetLogonNotifyWindowRequest.LogonNotifyWindow = Wnd;
 +
 +    Status = CsrClientCallServer((PCSR_API_MESSAGE)&Request,
 +                                 NULL,
 +                                 CSR_CREATE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpRosSetLogonNotifyWindow),
 +                                 sizeof(CSRSS_SET_LOGON_NOTIFY_WINDOW));
 +    if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
 +    {
 +        SetLastError(RtlNtStatusToDosError(Status));
 +        return FALSE;
 +    }
 +/// END HACK
 +
 +    return NtUserSetLogonNotifyWindow(Wnd);
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +UpdatePerUserSystemParameters(
 +   DWORD dwReserved,
 +   BOOL bEnable)
 +{
 +   return NtUserUpdatePerUserSystemParameters(dwReserved, bEnable);
 +}
 +
 +PTHREADINFO
 +GetW32ThreadInfo(VOID)
 +{
 +    PTHREADINFO ti;
 +
 +    ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
 +    if (ti == NULL)
 +    {
 +        /* create the THREADINFO structure */
 +        NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
 +        ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
 +    }
 +
 +    return ti;
 +}
 +
 +
 +/*
 + * GetUserObjectSecurity
 + *
 + * Retrieves security information for user object specified
 + * with handle 'hObject'. Descriptor returned in self-relative
 + * format.
 + *
 + * Arguments:
 + *  1) hObject - handle to an object to retrieve information for
 + *  2) pSecurityInfo - type of information to retrieve
 + *  3) pSecurityDescriptor - buffer which receives descriptor
 + *  4) dwLength - size, in bytes, of buffer 'pSecurityDescriptor'
 + *  5) pdwLengthNeeded - reseives actual size of descriptor
 + *
 + * Return Vaules:
 + *  TRUE on success
 + *  FALSE on failure, call GetLastError() for more information
 + */
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +GetUserObjectSecurity(
 +    IN HANDLE hObject,
 +    IN PSECURITY_INFORMATION pSecurityInfo,
 +    OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
 +    IN DWORD dwLength,
 +    OUT PDWORD pdwLengthNeeded
 +)
 +{
 +DWORD dwWin32Error;
 +NTSTATUS Status;
 +
 +
 +    Status = NtQuerySecurityObject(
 +        hObject,            // Object Handle
 +        *pSecurityInfo,     // Security Information
 +        pSecurityDescriptor,// Security Descriptor
 +        dwLength,           // Buffer Length
 +        pdwLengthNeeded     // Actual Length
 +    );
 +
 +    if ( ! NT_SUCCESS( Status ) ) {
 +        dwWin32Error = RtlNtStatusToDosError( Status );
 +        NtCurrentTeb()->LastErrorValue = dwWin32Error;
 +        return FALSE;
 +    }
 +
 +    return TRUE;
 +}
 +
 +
 +/*
 + * SetUserObjectSecurity
 + *
 + * Sets new security descriptor to user object specified by
 + * handle 'hObject'. Descriptor must be in self-relative format.
 + *
 + * Arguments:
 + *  1) hObject - handle to an object to set information for
 + *  2) pSecurityInfo - type of information to apply
 + *  3) pSecurityDescriptor - buffer which descriptor to set
 + *
 + * Return Vaules:
 + *  TRUE on success
 + *  FALSE on failure, call GetLastError() for more information
 + */
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +SetUserObjectSecurity(
 +    IN HANDLE hObject,
 +    IN PSECURITY_INFORMATION pSecurityInfo,
 +    IN PSECURITY_DESCRIPTOR pSecurityDescriptor
 +)
 +{
 +DWORD dwWin32Error;
 +NTSTATUS Status;
 +
 +
 +    Status = NtSetSecurityObject(
 +        hObject,            // Object Handle
 +        *pSecurityInfo,     // Security Information
 +        pSecurityDescriptor // Security Descriptor
 +    );
 +
 +    if ( ! NT_SUCCESS( Status ) ) {
 +        dwWin32Error = RtlNtStatusToDosError( Status );
 +        NtCurrentTeb()->LastErrorValue = dwWin32Error;
 +        return FALSE;
 +    }
 +
 +    return TRUE;
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +EndTask(
 +      HWND    hWnd,
 +      BOOL fShutDown,
 +      BOOL fForce)
 +{
 +    SendMessageW(hWnd, WM_CLOSE, 0, 0);
 +
 +    if (IsWindow(hWnd))
 +    {
 +        if (fForce)
 +            return DestroyWindow(hWnd);
 +        else
 +            return FALSE;
 +    }
 +
 +    return TRUE;
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +IsGUIThread(
 +    BOOL bConvert)
 +{
 +  PTHREADINFO ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
 +  if (ti == NULL)
 +  {
 +    if(bConvert)
 +    {
 +      NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
 +      if ((PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo) return TRUE;
 +      else
 +         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
 +    }
 +    return FALSE;
 +  }
 +  else
 +    return TRUE;
 +}
 +
 +BOOL
 +FASTCALL
 +TestWindowProcess(PWND Wnd)
 +{
 +   if (Wnd->head.pti == (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo)
 +      return TRUE;
 +   else
 +      return (NtUserQueryWindow(Wnd->head.h, QUERY_WINDOW_UNIQUE_PROCESS_ID) ==
 +              (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess );
 +}
 +
 +BOOL
 +FASTCALL
 +TestState(PWND pWnd, UINT Flag)
 +{
 +    UINT bit;
 +    bit = 1 << LOWORD(Flag);
 +    switch(HIWORD(Flag))
 +    {
 +       case 0: 
 +          return (pWnd->state & bit); 
 +       case 1:
 +          return (pWnd->state2 & bit);
 +       case 2:
 +          return (pWnd->ExStyle2 & bit);
 +    }
 +    return FALSE;
 +}
 +
 +PUSER_HANDLE_ENTRY
 +FASTCALL
 +GetUser32Handle(HANDLE handle)
 +{
 +    INT Index;
 +    USHORT generation;
 +
++    if (!handle) return NULL;
++
 +    Index = (((UINT_PTR)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
 +
 +    if (Index < 0 || Index >= gHandleTable->nb_handles)
 +        return NULL;
 +
 +    if (!gHandleEntries[Index].type || !gHandleEntries[Index].ptr)
 +        return NULL;
 +
 +    generation = (UINT_PTR)handle >> 16;
 +
 +    if (generation == gHandleEntries[Index].generation || !generation || generation == 0xffff)
 +        return &gHandleEntries[Index];
 +
 +    return NULL;
 +}
 +
 +/*
 + * Decide whether an object is located on the desktop or shared heap
 + */
 +static const BOOL g_ObjectHeapTypeShared[otEvent + 1] =
 +{
 +    FALSE, /* otFree (not used) */
 +    FALSE, /* otWindow */
 +    TRUE,  /* otMenu  FALSE */
 +    TRUE,  /* otCursorIcon */
 +    TRUE,  /* otSMWP */
 +    FALSE, /* otHook */
 +    FALSE, /* (not used) */
 +    FALSE, /* otCallProc */
 +    TRUE,  /* otAccel */
 +    FALSE, /* (not used) */
 +    FALSE, /* (not used) */
 +    FALSE, /* (not used) */
 +    TRUE,  /* otMonitor */
 +    FALSE, /* (not used) */
 +    FALSE, /* (not used) */
 +    TRUE   /* otEvent */
 +};
 +
 +//
 +// Validate Handle and return the pointer to the object.
 +//
 +PVOID
 +FASTCALL
 +ValidateHandle(HANDLE handle, UINT uType)
 +{
 +  PVOID ret;
 +  PUSER_HANDLE_ENTRY pEntry;
 +
 +  ASSERT(uType <= otEvent);
 +
 +  pEntry = GetUser32Handle(handle);
 +
 +  if (pEntry && uType == 0)
 +      uType = pEntry->type;
 +
 +// Must have an entry and must be the same type!
 +  if ( (!pEntry) ||
 +        (pEntry->type != uType) ||
 +        !pEntry->ptr ||
 +        (pEntry->flags & HANDLEENTRY_INDESTROY) )
 +  {
 +     switch ( uType )
 +     {  // Test (with wine too) confirms these results!
 +        case otWindow:
 +          SetLastError(ERROR_INVALID_WINDOW_HANDLE);
 +          break;
 +        case otMenu:
 +          SetLastError(ERROR_INVALID_MENU_HANDLE);
 +          break;
 +        case otCursorIcon:
 +          SetLastError(ERROR_INVALID_CURSOR_HANDLE);
 +          break;
 +        case otSMWP:
 +          SetLastError(ERROR_INVALID_DWP_HANDLE);
 +          break;
 +        case otHook:
 +          SetLastError(ERROR_INVALID_HOOK_HANDLE);
 +          break;
 +        case otAccel:
 +          SetLastError(ERROR_INVALID_ACCEL_HANDLE);
 +          break;
 +        default:
 +          SetLastError(ERROR_INVALID_HANDLE);
 +          break;
 +    }
 +    return NULL;
 +  }
 +
 +  if (g_ObjectHeapTypeShared[uType])
 +    ret = SharedPtrToUser(pEntry->ptr);
 +  else
 +    ret = DesktopPtrToUser(pEntry->ptr);
 +
 +  return ret;
 +}
 +
 +//
 +// Validate Handle and return the pointer to the object.
 +//
 +PVOID
 +FASTCALL
 +ValidateHandleNoErr(HANDLE handle, UINT uType)
 +{
 +  PVOID ret;
 +  PUSER_HANDLE_ENTRY pEntry;
 +
 +  ASSERT(uType <= otEvent);
 +
 +  pEntry = GetUser32Handle(handle);
 +
 +  if (pEntry && uType == 0)
 +      uType = pEntry->type;
 +
 +// Must have an entry and must be the same type!
 +  if ( (!pEntry) || (pEntry->type != uType) || !pEntry->ptr )
 +    return NULL;
 +
 +  if (g_ObjectHeapTypeShared[uType])
 +    ret = SharedPtrToUser(pEntry->ptr);
 +  else
 +    ret = DesktopPtrToUser(pEntry->ptr);
 +
 +  return ret;
 +}
 +
 +//
 +// Validate a callproc handle and return the pointer to the object.
 +//
 +PCALLPROCDATA
 +FASTCALL
 +ValidateCallProc(HANDLE hCallProc)
 +{
 +  PUSER_HANDLE_ENTRY pEntry;
 +
 +  PCALLPROCDATA CallProc = ValidateHandle(hCallProc, otCallProc);
 +
 +  pEntry = GetUser32Handle(hCallProc);
 +
 +  if (CallProc != NULL && pEntry->ppi == g_ppi)
 +     return CallProc;
 +
 +  return NULL;
 +}
 +
 +
 +//
 +// Validate a window handle and return the pointer to the object.
 +//
 +PWND
 +FASTCALL
 +ValidateHwnd(HWND hwnd)
 +{
-     if (hwnd == ClientInfo->CallbackWnd.hWnd)
 +    PCLIENTINFO ClientInfo = GetWin32ClientInfo();
 +    ASSERT(ClientInfo != NULL);
 +
 +    /* See if the window is cached */
-     Wnd = ValidateHandle((HANDLE)hwnd, otWindow);
-     if (Wnd != NULL)
-     {
-         return Wnd;
-     }
-     return NULL;
++    if (hwnd && hwnd == ClientInfo->CallbackWnd.hWnd)
 +        return ClientInfo->CallbackWnd.pWnd;
 +
++    return ValidateHandle((HANDLE)hwnd, otWindow);
 +}
 +
 +//
 +// Validate a window handle and return the pointer to the object.
 +//
 +PWND
 +FASTCALL
 +ValidateHwndNoErr(HWND hwnd)
 +{
 +    PWND Wnd;
 +    PCLIENTINFO ClientInfo = GetWin32ClientInfo();
 +    ASSERT(ClientInfo != NULL);
 +
 +    /* See if the window is cached */
 +    if (hwnd == ClientInfo->CallbackWnd.hWnd)
 +        return ClientInfo->CallbackWnd.pWnd;
 +
 +    Wnd = ValidateHandleNoErr((HANDLE)hwnd, otWindow);
 +    if (Wnd != NULL)
 +    {
 +        return Wnd;
 +    }
 +
 +    return NULL;
 +}
 +
 +PWND
 +FASTCALL
 +GetThreadDesktopWnd(VOID)
 +{
 +    PWND Wnd = GetThreadDesktopInfo()->spwnd;
 +    if (Wnd != NULL)
 +        Wnd = DesktopPtrToUser(Wnd);
 +    return Wnd;
 +}
 +
 +//
 +// Validate a window handle and return the pointer to the object.
 +//
 +PWND
 +FASTCALL
 +ValidateHwndOrDesk(HWND hwnd)
 +{
 +    if (hwnd == HWND_DESKTOP)
 +        return GetThreadDesktopWnd();
 +
 +    return ValidateHwnd(hwnd);
 +}
 +
 +/*
 + * @implemented
 + */
 +DWORD WINAPI WCSToMBEx(WORD CodePage,LPWSTR UnicodeString,LONG UnicodeSize,LPSTR *MBString,LONG MBSize,BOOL Allocate)
 +{
 +      DWORD Size;
 +      if (UnicodeSize == -1)
 +      {
 +              UnicodeSize = wcslen(UnicodeString)+1;
 +      }
 +      if (MBSize == -1)
 +      {
 +              if (!Allocate)
 +              {
 +                      return 0;
 +              }
 +              MBSize = UnicodeSize * 2;
 +      }
 +      if (Allocate)
 +      {
 +              LPSTR SafeString = RtlAllocateHeap(GetProcessHeap(), 0, MBSize);
 +        if (SafeString == NULL)
 +            return 0;
 +        *MBString = SafeString;
 +      }
 +      if (CodePage == 0)
 +      {
 +              RtlUnicodeToMultiByteN(*MBString,MBSize,&Size,UnicodeString,UnicodeSize);
 +      }
 +      else
 +      {
 +              WideCharToMultiByte(CodePage,0,UnicodeString,UnicodeSize,*MBString,MBSize,0,0);
 +      }
 +      return UnicodeSize;
 +}
 +
 +/*
 + * @implemented
 + */
 +DWORD WINAPI MBToWCSEx(WORD CodePage,LPSTR MBString,LONG MBSize,LPWSTR *UnicodeString,LONG UnicodeSize,BOOL Allocate)
 +{
 +      DWORD Size;
 +      if (MBSize == -1)
 +      {
 +              MBSize = strlen(MBString)+1;
 +      }
 +      if (UnicodeSize == -1)
 +      {
 +              if (!Allocate)
 +              {
 +                      return 0;
 +              }
 +              UnicodeSize = MBSize;
 +      }
 +      if (Allocate)
 +      {
 +              LPWSTR SafeString = RtlAllocateHeap(GetProcessHeap(), 0, UnicodeSize);
 +        if (SafeString == NULL)
 +            return 0;
 +        *UnicodeString = SafeString;
 +      }
 +      UnicodeSize *= sizeof(WCHAR);
 +      if (CodePage == 0)
 +      {
 +              RtlMultiByteToUnicodeN(*UnicodeString,UnicodeSize,&Size,MBString,MBSize);
 +      }
 +      else
 +      {
 +              Size = MultiByteToWideChar(CodePage,0,MBString,MBSize,*UnicodeString,UnicodeSize);
 +      }
 +      return Size;
 +}
Simple merge