Example #1
0
/***********************************************************************
 *           init_user_process_params
 *
 * Fill the RTL_USER_PROCESS_PARAMETERS structure from the server.
 */
static NTSTATUS init_user_process_params( SIZE_T data_size, HANDLE *exe_file )
{
    void *ptr;
    WCHAR *src, *dst;
    SIZE_T info_size, env_size, size, alloc_size;
    NTSTATUS status;
    startup_info_t *info;
    RTL_USER_PROCESS_PARAMETERS *params = NULL;

    if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, data_size )))
        return STATUS_NO_MEMORY;

    SERVER_START_REQ( get_startup_info )
    {
        wine_server_set_reply( req, info, data_size );
        if (!(status = wine_server_call( req )))
        {
            data_size = wine_server_reply_size( reply );
            info_size = reply->info_size;
            env_size  = data_size - info_size;
            *exe_file = wine_server_ptr_handle( reply->exe_file );
        }
    }
    SERVER_END_REQ;
    if (status != STATUS_SUCCESS) goto done;

    size = sizeof(*params);
    size += MAX_NT_PATH_LENGTH * sizeof(WCHAR);
    size += info->dllpath_len + sizeof(WCHAR);
    size += info->imagepath_len + sizeof(WCHAR);
    size += info->cmdline_len + sizeof(WCHAR);
    size += info->title_len + sizeof(WCHAR);
    size += info->desktop_len + sizeof(WCHAR);
    size += info->shellinfo_len + sizeof(WCHAR);
    size += info->runtime_len + sizeof(WCHAR);

    alloc_size = size;
    status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&params, 0, &alloc_size,
                                      MEM_COMMIT, PAGE_READWRITE );
    if (status != STATUS_SUCCESS) goto done;

    NtCurrentTeb()->Peb->ProcessParameters = params;
    params->AllocationSize  = alloc_size;
    params->Size            = size;
    params->Flags           = PROCESS_PARAMS_FLAG_NORMALIZED;
    params->DebugFlags      = info->debug_flags;
    params->ConsoleHandle   = wine_server_ptr_handle( info->console );
    params->ConsoleFlags    = info->console_flags;
    params->hStdInput       = wine_server_ptr_handle( info->hstdin );
    params->hStdOutput      = wine_server_ptr_handle( info->hstdout );
    params->hStdError       = wine_server_ptr_handle( info->hstderr );
    params->dwX             = info->x;
    params->dwY             = info->y;
    params->dwXSize         = info->xsize;
    params->dwYSize         = info->ysize;
    params->dwXCountChars   = info->xchars;
    params->dwYCountChars   = info->ychars;
    params->dwFillAttribute = info->attribute;
    params->dwFlags         = info->flags;
    params->wShowWindow     = info->show;

    src = (WCHAR *)(info + 1);
    dst = (WCHAR *)(params + 1);

    /* current directory needs more space */
    get_unicode_string( &params->CurrentDirectory.DosPath, &src, &dst, info->curdir_len );
    params->CurrentDirectory.DosPath.MaximumLength = MAX_NT_PATH_LENGTH * sizeof(WCHAR);
    dst = (WCHAR *)(params + 1) + MAX_NT_PATH_LENGTH;

    get_unicode_string( &params->DllPath, &src, &dst, info->dllpath_len );
    get_unicode_string( &params->ImagePathName, &src, &dst, info->imagepath_len );
    get_unicode_string( &params->CommandLine, &src, &dst, info->cmdline_len );
    get_unicode_string( &params->WindowTitle, &src, &dst, info->title_len );
    get_unicode_string( &params->Desktop, &src, &dst, info->desktop_len );
    get_unicode_string( &params->ShellInfo, &src, &dst, info->shellinfo_len );

    /* runtime info isn't a real string */
    params->RuntimeInfo.Buffer = dst;
    params->RuntimeInfo.Length = params->RuntimeInfo.MaximumLength = info->runtime_len;
    memcpy( dst, src, info->runtime_len );

    /* environment needs to be a separate memory block */
    ptr = NULL;
    alloc_size = max( 1, env_size );
    status = NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &alloc_size,
                                      MEM_COMMIT, PAGE_READWRITE );
    if (status != STATUS_SUCCESS) goto done;
    memcpy( ptr, (char *)info + info_size, env_size );
    params->Environment = ptr;

done:
    RtlFreeHeap( GetProcessHeap(), 0, info );
    return status;
}
Example #2
0
/***********************************************************************
 *              GetUserObjectInformationW   (USER32.@)
 */
BOOL WINAPI GetUserObjectInformationW( HANDLE handle, INT index, LPVOID info, DWORD len, LPDWORD needed )
{
    static const WCHAR desktopW[] = { 'D','e','s','k','t','o','p',0 };
    static const WCHAR winstationW[] = { 'W','i','n','d','o','w','S','t','a','t','i','o','n',0 };
    BOOL ret;

    switch(index)
    {
    case UOI_FLAGS:
        {
            USEROBJECTFLAGS *obj_flags = info;
            if (needed) *needed = sizeof(*obj_flags);
            if (len < sizeof(*obj_flags))
            {
                SetLastError( ERROR_BUFFER_OVERFLOW );
                return FALSE;
            }
            SERVER_START_REQ( set_user_object_info )
            {
                req->handle    = wine_server_obj_handle( handle );
                req->flags     = 0;
                ret = !wine_server_call_err( req );
                if (ret)
                {
                    /* FIXME: inherit flag */
                    obj_flags->dwFlags = reply->old_obj_flags;
                }
            }
            SERVER_END_REQ;
        }
        return ret;

    case UOI_TYPE:
        SERVER_START_REQ( set_user_object_info )
        {
            req->handle = wine_server_obj_handle( handle );
            req->flags  = 0;
            ret = !wine_server_call_err( req );
            if (ret)
            {
                size_t size = reply->is_desktop ? sizeof(desktopW) : sizeof(winstationW);
                if (needed) *needed = size;
                if (len < size)
                {
                    SetLastError( ERROR_INSUFFICIENT_BUFFER );
                    ret = FALSE;
                }
                else memcpy( info, reply->is_desktop ? desktopW : winstationW, size );
            }
        }
        SERVER_END_REQ;
        return ret;

    case UOI_NAME:
        {
            WCHAR buffer[MAX_PATH];
            SERVER_START_REQ( set_user_object_info )
            {
                req->handle = wine_server_obj_handle( handle );
                req->flags  = 0;
                wine_server_set_reply( req, buffer, sizeof(buffer) - sizeof(WCHAR) );
                ret = !wine_server_call_err( req );
                if (ret)
                {
                    size_t size = wine_server_reply_size( reply );
                    buffer[size / sizeof(WCHAR)] = 0;
                    size += sizeof(WCHAR);
                    if (needed) *needed = size;
                    if (len < size)
                    {
                        SetLastError( ERROR_INSUFFICIENT_BUFFER );
                        ret = FALSE;
                    }
                    else memcpy( info, buffer, size );
                }
            }
            SERVER_END_REQ;
        }
        return ret;

    case UOI_USER_SID:
        FIXME( "not supported index %d\n", index );
        /* fall through */
    default:
        SetLastError( ERROR_INVALID_PARAMETER );
        return FALSE;
    }
}
/******************************************************************************
 *           WaitForDebugEvent   (KERNEL32.@)
 *
 *  Waits for a debugging event to occur in a process being debugged before
 *  filling out the debug event structure.
 *
 * PARAMS
 *  event   [O] Address of structure for event information.
 *  timeout [I] Number of milliseconds to wait for event.
 *
 * RETURNS
 *
 *  Returns true if a debug event occurred and false if the call timed out.
 */
BOOL WINAPI WaitForDebugEvent(
    LPDEBUG_EVENT event,
    DWORD         timeout)
{
    BOOL ret;
    DWORD res;
    int i;

    for (;;)
    {
        HANDLE wait = 0;
        debug_event_t data;
        SERVER_START_REQ( wait_debug_event )
        {
            req->get_handle = (timeout != 0);
            wine_server_set_reply( req, &data, sizeof(data) );
            if (!(ret = !wine_server_call_err( req ))) goto done;

            if (!wine_server_reply_size(reply))  /* timeout */
            {
                wait = wine_server_ptr_handle( reply->wait );
                ret = FALSE;
                goto done;
            }
            event->dwDebugEventCode = data.code;
            event->dwProcessId      = (DWORD)reply->pid;
            event->dwThreadId       = (DWORD)reply->tid;
            switch(data.code)
            {
            case EXCEPTION_DEBUG_EVENT:
                if (data.exception.exc_code == DBG_PRINTEXCEPTION_C && data.exception.nb_params >= 2)
                {
                    event->dwDebugEventCode = OUTPUT_DEBUG_STRING_EVENT;
                    event->u.DebugString.lpDebugStringData  = wine_server_get_ptr( data.exception.params[1] );
                    event->u.DebugString.fUnicode           = FALSE;
                    event->u.DebugString.nDebugStringLength = data.exception.params[0];
                    break;
                }
                else if (data.exception.exc_code == DBG_RIPEXCEPTION && data.exception.nb_params >= 2)
                {
                    event->dwDebugEventCode = RIP_EVENT;
                    event->u.RipInfo.dwError = data.exception.params[0];
                    event->u.RipInfo.dwType  = data.exception.params[1];
                    break;
                }
                event->u.Exception.dwFirstChance = data.exception.first;
                event->u.Exception.ExceptionRecord.ExceptionCode    = data.exception.exc_code;
                event->u.Exception.ExceptionRecord.ExceptionFlags   = data.exception.flags;
                event->u.Exception.ExceptionRecord.ExceptionRecord  = wine_server_get_ptr( data.exception.record );
                event->u.Exception.ExceptionRecord.ExceptionAddress = wine_server_get_ptr( data.exception.address );
                event->u.Exception.ExceptionRecord.NumberParameters = data.exception.nb_params;
                for (i = 0; i < data.exception.nb_params; i++)
                    event->u.Exception.ExceptionRecord.ExceptionInformation[i] = data.exception.params[i];
                break;
            case CREATE_THREAD_DEBUG_EVENT:
                event->u.CreateThread.hThread           = wine_server_ptr_handle( data.create_thread.handle );
                event->u.CreateThread.lpThreadLocalBase = wine_server_get_ptr( data.create_thread.teb );
                event->u.CreateThread.lpStartAddress    = wine_server_get_ptr( data.create_thread.start );
                break;
            case CREATE_PROCESS_DEBUG_EVENT:
                event->u.CreateProcessInfo.hFile                 = wine_server_ptr_handle( data.create_process.file );
                event->u.CreateProcessInfo.hProcess              = wine_server_ptr_handle( data.create_process.process );
                event->u.CreateProcessInfo.hThread               = wine_server_ptr_handle( data.create_process.thread );
                event->u.CreateProcessInfo.lpBaseOfImage         = wine_server_get_ptr( data.create_process.base );
                event->u.CreateProcessInfo.dwDebugInfoFileOffset = data.create_process.dbg_offset;
                event->u.CreateProcessInfo.nDebugInfoSize        = data.create_process.dbg_size;
                event->u.CreateProcessInfo.lpThreadLocalBase     = wine_server_get_ptr( data.create_process.teb );
                event->u.CreateProcessInfo.lpStartAddress        = wine_server_get_ptr( data.create_process.start );
                event->u.CreateProcessInfo.lpImageName           = wine_server_get_ptr( data.create_process.name );
                event->u.CreateProcessInfo.fUnicode              = data.create_process.unicode;
                break;
            case EXIT_THREAD_DEBUG_EVENT:
                event->u.ExitThread.dwExitCode = data.exit.exit_code;
                break;
            case EXIT_PROCESS_DEBUG_EVENT:
                event->u.ExitProcess.dwExitCode = data.exit.exit_code;
                break;
            case LOAD_DLL_DEBUG_EVENT:
                event->u.LoadDll.hFile                 = wine_server_ptr_handle( data.load_dll.handle );
                event->u.LoadDll.lpBaseOfDll           = wine_server_get_ptr( data.load_dll.base );
                event->u.LoadDll.dwDebugInfoFileOffset = data.load_dll.dbg_offset;
                event->u.LoadDll.nDebugInfoSize        = data.load_dll.dbg_size;
                event->u.LoadDll.lpImageName           = wine_server_get_ptr( data.load_dll.name );
                event->u.LoadDll.fUnicode              = data.load_dll.unicode;
                break;
            case UNLOAD_DLL_DEBUG_EVENT:
                event->u.UnloadDll.lpBaseOfDll = wine_server_get_ptr( data.unload_dll.base );
                break;
            }
        done:
            /* nothing */ ;
        }
        SERVER_END_REQ;
        if (ret) return TRUE;
        if (!wait) break;
        res = WaitForSingleObject( wait, timeout );
        CloseHandle( wait );
        if (res != STATUS_WAIT_0) break;
    }
    SetLastError( ERROR_SEM_TIMEOUT );
    return FALSE;
}