Ejemplo n.º 1
0
/* allocate the win16 TIB for a new 16-bit task */
static WIN16_SUBSYSTEM_TIB *allocate_win16_tib( TDB *pTask )
{
    WCHAR path[MAX_PATH];
    WIN16_SUBSYSTEM_TIB *tib;
    UNICODE_STRING *curdir;
    NE_MODULE *pModule = NE_GetPtr( pTask->hModule );

    if (!(tib = HeapAlloc( GetProcessHeap(), 0, sizeof(*tib) ))) return NULL;
    MultiByteToWideChar( CP_ACP, 0, NE_MODULE_NAME(pModule), -1, path, MAX_PATH );
    GetLongPathNameW( path, path, MAX_PATH );
    if (RtlCreateUnicodeString( &tib->exe_str, path )) tib->exe_name = &tib->exe_str;
    else tib->exe_name = NULL;

    RtlAcquirePebLock();
    if (NtCurrentTeb()->Tib.SubSystemTib)
        curdir = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir.DosPath;
    else
        curdir = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.DosPath;
    tib->curdir.DosPath.MaximumLength = sizeof(tib->curdir_buffer);
    tib->curdir.DosPath.Length = min( curdir->Length, tib->curdir.DosPath.MaximumLength-sizeof(WCHAR) );
    tib->curdir.DosPath.Buffer = tib->curdir_buffer;
    tib->curdir.Handle = 0;
    memcpy( tib->curdir_buffer, curdir->Buffer, tib->curdir.DosPath.Length );
    tib->curdir_buffer[tib->curdir.DosPath.Length/sizeof(WCHAR)] = 0;
    RtlReleasePebLock();
    return tib;
}
Ejemplo n.º 2
0
/***********************************************************************
 *           GetEnvironmentStringsA   (KERNEL32.@)
 *           GetEnvironmentStrings    (KERNEL32.@)
 */
LPSTR WINAPI GetEnvironmentStringsA(void)
{
    LPWSTR      ptrW;
    unsigned    len, slen;
    LPSTR       ret, ptrA;

    RtlAcquirePebLock();

    len = 1;

    ptrW = NtCurrentTeb()->Peb->ProcessParameters->Environment;
    while (*ptrW)
    {
        slen = strlenW(ptrW) + 1;
        len += WideCharToMultiByte( CP_ACP, 0, ptrW, slen, NULL, 0, NULL, NULL );
        ptrW += slen;
    }

    if ((ret = HeapAlloc( GetProcessHeap(), 0, len )) != NULL)
    {
        ptrW = NtCurrentTeb()->Peb->ProcessParameters->Environment;
        ptrA = ret;
        while (*ptrW)
        {
            slen = strlenW(ptrW) + 1;
            WideCharToMultiByte( CP_ACP, 0, ptrW, slen, ptrA, len, NULL, NULL );
            ptrW += slen;
            ptrA += strlen(ptrA) + 1;
        }
        *ptrA = 0;
    }

    RtlReleasePebLock();
    return ret;
}
Ejemplo n.º 3
0
/***********************************************************************
 *           start_thread
 *
 * Startup routine for a newly created thread.
 */
static void start_thread( struct startup_info *info )
{
    TEB *teb = info->teb;
    struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;
    PRTL_THREAD_START_ROUTINE func = info->entry_point;
    void *arg = info->entry_arg;
    struct debug_info debug_info;

    debug_info.str_pos = debug_info.strings;
    debug_info.out_pos = debug_info.output;
    thread_data->debug_info = &debug_info;
    thread_data->pthread_id = pthread_self();

    signal_init_thread( teb );
    server_init_thread( func );
    pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );

    RtlAcquirePebLock();
    InsertHeadList( &tls_links, &teb->TlsLinks );
    RtlReleasePebLock();

    MODULE_DllThreadAttach( NULL );

    if (TRACE_ON(relay))
        DPRINTF( "%04x:Starting thread proc %p (arg=%p)\n", GetCurrentThreadId(), func, arg );

    call_thread_entry_point( (LPTHREAD_START_ROUTINE)func, arg );
}
Ejemplo n.º 4
0
/******************************************************************
 *		RtlSetCurrentEnvironment        [NTDLL.@]
 *
 */
void WINAPI RtlSetCurrentEnvironment(PWSTR new_env, PWSTR* old_env)
{
    TRACE("(%p %p)\n", new_env, old_env);

    RtlAcquirePebLock();

    if (old_env) *old_env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
    NtCurrentTeb()->Peb->ProcessParameters->Environment = new_env;

    RtlReleasePebLock();
}
Ejemplo n.º 5
0
/******************************************************************
 *		ENV_CopyStartupInformation (internal)
 *
 * Creates the STARTUPINFO information from the ntdll information
 */
void ENV_CopyStartupInformation(void)
{
    RTL_USER_PROCESS_PARAMETERS* rupp;
    ANSI_STRING         ansi;

    RtlAcquirePebLock();

    rupp = NtCurrentTeb()->Peb->ProcessParameters;

    startup_infoW.cb                   = sizeof(startup_infoW);
    startup_infoW.lpReserved           = NULL;
    startup_infoW.lpDesktop            = rupp->Desktop.Buffer;
    startup_infoW.lpTitle              = rupp->WindowTitle.Buffer;
    startup_infoW.dwX                  = rupp->dwX;
    startup_infoW.dwY                  = rupp->dwY;
    startup_infoW.dwXSize              = rupp->dwXSize;
    startup_infoW.dwYSize              = rupp->dwYSize;
    startup_infoW.dwXCountChars        = rupp->dwXCountChars;
    startup_infoW.dwYCountChars        = rupp->dwYCountChars;
    startup_infoW.dwFillAttribute      = rupp->dwFillAttribute;
    startup_infoW.dwFlags              = rupp->dwFlags;
    startup_infoW.wShowWindow          = rupp->wShowWindow;
    startup_infoW.cbReserved2          = rupp->RuntimeInfo.MaximumLength;
    startup_infoW.lpReserved2          = rupp->RuntimeInfo.MaximumLength ? (void*)rupp->RuntimeInfo.Buffer : NULL;
    startup_infoW.hStdInput            = rupp->hStdInput;
    startup_infoW.hStdOutput           = rupp->hStdOutput;
    startup_infoW.hStdError            = rupp->hStdError;

    startup_infoA.cb                   = sizeof(startup_infoA);
    startup_infoA.lpReserved           = NULL;
    startup_infoA.lpDesktop = (rupp->Desktop.Length &&
                               RtlUnicodeStringToAnsiString( &ansi, &rupp->Desktop, TRUE) == STATUS_SUCCESS) ?
                              ansi.Buffer : NULL;
    startup_infoA.lpTitle = (rupp->WindowTitle.Length &&
                             RtlUnicodeStringToAnsiString( &ansi, &rupp->WindowTitle, TRUE) == STATUS_SUCCESS) ?
                            ansi.Buffer : NULL;
    startup_infoA.dwX                  = rupp->dwX;
    startup_infoA.dwY                  = rupp->dwY;
    startup_infoA.dwXSize              = rupp->dwXSize;
    startup_infoA.dwYSize              = rupp->dwYSize;
    startup_infoA.dwXCountChars        = rupp->dwXCountChars;
    startup_infoA.dwYCountChars        = rupp->dwYCountChars;
    startup_infoA.dwFillAttribute      = rupp->dwFillAttribute;
    startup_infoA.dwFlags              = rupp->dwFlags;
    startup_infoA.wShowWindow          = rupp->wShowWindow;
    startup_infoA.cbReserved2          = rupp->RuntimeInfo.MaximumLength;
    startup_infoA.lpReserved2          = rupp->RuntimeInfo.MaximumLength ? (void*)rupp->RuntimeInfo.Buffer : NULL;
    startup_infoA.hStdInput            = rupp->hStdInput;
    startup_infoA.hStdOutput           = rupp->hStdOutput;
    startup_infoA.hStdError            = rupp->hStdError;

    RtlReleasePebLock();
}
Ejemplo n.º 6
0
/*
 * @implemented
 */
DWORD
WINAPI
TlsAlloc(VOID)
{
    ULONG Index;

    RtlAcquirePebLock();

    /* Try to get regular TEB slot. */
    Index = RtlFindClearBitsAndSet(NtCurrentPeb()->TlsBitmap, 1, 0);
    if (Index == ~0U)
    {
        /* If it fails, try to find expansion TEB slot. */
        Index = RtlFindClearBitsAndSet(NtCurrentPeb()->TlsExpansionBitmap, 1, 0);
        if (Index != ~0U)
        {
            if (NtCurrentTeb()->TlsExpansionSlots == NULL)
            {
                NtCurrentTeb()->TlsExpansionSlots = HeapAlloc(RtlGetProcessHeap(),
                                                              HEAP_ZERO_MEMORY,
                                                              TLS_EXPANSION_SLOTS *
                                                              sizeof(PVOID));
            }

            if (NtCurrentTeb()->TlsExpansionSlots == NULL)
            {
                RtlClearBits(NtCurrentPeb()->TlsExpansionBitmap, Index, 1);
                Index = ~0;
                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            }
            else
            {
                /* Clear the value. */
                NtCurrentTeb()->TlsExpansionSlots[Index] = 0;
                Index += TLS_MINIMUM_AVAILABLE;
            }
        }
        else
        {
            SetLastError(ERROR_NO_MORE_ITEMS);
        }
    }
    else
    {
        /* Clear the value. */
        NtCurrentTeb()->TlsSlots[Index] = 0;
    }

    RtlReleasePebLock();

    return Index;
}
Ejemplo n.º 7
0
/*
 * @implemented
 */
BOOL
WINAPI
TlsFree(DWORD Index)
{
    BOOL BitSet;

    if (Index >= TLS_EXPANSION_SLOTS + TLS_MINIMUM_AVAILABLE)
    {
        SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
        return FALSE;
    }

    RtlAcquirePebLock();

    if (Index >= TLS_MINIMUM_AVAILABLE)
    {
        BitSet = RtlAreBitsSet(NtCurrentPeb()->TlsExpansionBitmap,
                               Index - TLS_MINIMUM_AVAILABLE,
                               1);

       if (BitSet)
           RtlClearBits(NtCurrentPeb()->TlsExpansionBitmap,
                        Index - TLS_MINIMUM_AVAILABLE,
                        1);
    }
    else
    {
        BitSet = RtlAreBitsSet(NtCurrentPeb()->TlsBitmap, Index, 1);
        if (BitSet)
            RtlClearBits(NtCurrentPeb()->TlsBitmap, Index, 1);
    }

    if (BitSet)
    {
        /* Clear the TLS cells (slots) in all threads of the current process. */
        NtSetInformationThread(NtCurrentThread(),
                               ThreadZeroTlsCell,
                               &Index,
                               sizeof(DWORD));
    }
    else
    {
        SetLastError(ERROR_INVALID_PARAMETER);
    }

    RtlReleasePebLock();

    return BitSet;
}
Ejemplo n.º 8
0
/***********************************************************************
 *           GetCommandLineA      (KERNEL32.@)
 *
 * WARNING: there's a Windows incompatibility lurking here !
 * Win32s always includes the full path of the program file,
 * whereas Windows NT only returns the full file path plus arguments
 * in case the program has been started with a full path.
 * Win9x seems to have inherited NT behaviour.
 *
 * Note that both Start Menu Execute and Explorer start programs with
 * fully specified quoted app file paths, which is why probably the only case
 * where you'll see single file names is in case of direct launch
 * via CreateProcess or WinExec.
 *
 * Perhaps we should take care of Win3.1 programs here (Win32s "feature").
 *
 * References: MS KB article q102762.txt (special Win32s handling)
 */
LPSTR WINAPI GetCommandLineA(void)
{
    static char *cmdlineA;  /* ASCII command line */

    if (!cmdlineA) /* make an ansi version if we don't have it */
    {
        ANSI_STRING     ansi;
        RtlAcquirePebLock();

        cmdlineA = (RtlUnicodeStringToAnsiString( &ansi, &NtCurrentTeb()->Peb->ProcessParameters->CommandLine, TRUE) == STATUS_SUCCESS) ?
                   ansi.Buffer : NULL;
        RtlReleasePebLock();
    }
    return cmdlineA;
}
Ejemplo n.º 9
0
/***********************************************************************
 *           exit_thread
 */
void exit_thread( int status )
{
    static void *prev_teb;
    TEB *teb;

    if (status)  /* send the exit code to the server (0 is already the default) */
    {
        SERVER_START_REQ( terminate_thread )
        {
            req->handle    = wine_server_obj_handle( GetCurrentThread() );
            req->exit_code = status;
            wine_server_call( req );
        }
        SERVER_END_REQ;
    }

    if (interlocked_xchg_add( &nb_threads, -1 ) <= 1)
    {
        LdrShutdownProcess();
        exit( status );
    }

    LdrShutdownThread();
    RtlAcquirePebLock();
    RemoveEntryList( &NtCurrentTeb()->TlsLinks );
    RtlReleasePebLock();
    RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->FlsSlots );
    RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->TlsExpansionSlots );

    pthread_sigmask( SIG_BLOCK, &server_block_set, NULL );

    if ((teb = interlocked_xchg_ptr( &prev_teb, NtCurrentTeb() )))
    {
        struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)teb->SpareBytes1;

        if (thread_data->pthread_id)
        {
            pthread_join( thread_data->pthread_id, NULL );
            signal_free_thread( teb );
        }
    }

    close( ntdll_get_thread_data()->wait_fd[0] );
    close( ntdll_get_thread_data()->wait_fd[1] );
    close( ntdll_get_thread_data()->reply_fd );
    close( ntdll_get_thread_data()->request_fd );
    pthread_exit( UIntToPtr(status) );
}
Ejemplo n.º 10
0
/****************************************************************************
 *		UTUnRegister (KERNEL32.@)
 */
VOID WINAPI UTUnRegister( HMODULE hModule )
{
    UTINFO *ut;
    HMODULE16 hModule16 = 0;

    RtlAcquirePebLock();
    ut = UTFind( hModule );
    if ( ut )
    {
        hModule16 = ut->hModule16;
        UTFree( ut );
    }
    RtlReleasePebLock();

    if ( hModule16 )
        FreeLibrary16( hModule16 );
}
Ejemplo n.º 11
0
/*
 * @implemented
 */
VOID NTAPI
RtlSetCurrentEnvironment(PWSTR NewEnvironment,
                         PWSTR *OldEnvironment)
{
   PVOID EnvPtr;

   DPRINT("NewEnvironment 0x%p OldEnvironment 0x%p\n",
          NewEnvironment, OldEnvironment);

   RtlAcquirePebLock();

   EnvPtr = NtCurrentPeb()->ProcessParameters->Environment;
   NtCurrentPeb()->ProcessParameters->Environment = NewEnvironment;

   if (OldEnvironment != NULL)
      *OldEnvironment = EnvPtr;

   RtlReleasePebLock();
}
Ejemplo n.º 12
0
/*
 * @implemented
 */
BOOL
WINAPI
FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData)
{
    PVOID *ppFlsSlots;
    TEB *pTeb = NtCurrentTeb();

    if(dwFlsIndex >= 128) goto l_InvalidParam;

    ppFlsSlots = pTeb->FlsData;

    if (ppFlsSlots == NULL)
    {
        PEB *pPeb = pTeb->ProcessEnvironmentBlock;

        ppFlsSlots = RtlAllocateHeap(pPeb->ProcessHeap,
                                     HEAP_ZERO_MEMORY,
                                     (128 + 2) * sizeof(PVOID));
        if(ppFlsSlots == NULL) goto l_OutOfMemory;

        pTeb->FlsData = ppFlsSlots;

        RtlAcquirePebLock();

        /* TODO: initialization */

        RtlReleasePebLock();
    }

    ppFlsSlots[dwFlsIndex + 2] = lpFlsData;

    return TRUE;

l_OutOfMemory:
    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
    goto l_Fail;

l_InvalidParam:
    SetLastError(ERROR_INVALID_PARAMETER);

l_Fail:
    return FALSE;
}
Ejemplo n.º 13
0
/******************************************************************
 *		RtlQueryEnvironmentVariable_U   [NTDLL.@]
 *
 * NOTES: when the buffer is too small, the string is not written, but if the
 *      terminating null char is the only char that cannot be written, then
 *      all chars (except the null) are written and success is returned
 *      (behavior of Win2k at least)
 */
NTSTATUS WINAPI RtlQueryEnvironmentVariable_U(PWSTR env,
                                              PUNICODE_STRING name,
                                              PUNICODE_STRING value)
{
    NTSTATUS    nts = STATUS_VARIABLE_NOT_FOUND;
    PCWSTR      var;
    unsigned    namelen;

    TRACE("%p %s %p\n", env, debugstr_us(name), value);

    value->Length = 0;
    namelen = name->Length / sizeof(WCHAR);
    if (!namelen) return nts;

    if (!env)
    {
        RtlAcquirePebLock();
        var = NtCurrentTeb()->Peb->ProcessParameters->Environment;
    }
    else var = env;

    var = ENV_FindVariable(var, name->Buffer, namelen);
    if (var != NULL)
    {
        value->Length = strlenW(var) * sizeof(WCHAR);

        if (value->Length <= value->MaximumLength)
        {
            memmove(value->Buffer, var, min(value->Length + sizeof(WCHAR), value->MaximumLength));
            nts = STATUS_SUCCESS;
        }
        else nts = STATUS_BUFFER_TOO_SMALL;
    }

    if (!env) RtlReleasePebLock();

    return nts;
}
Ejemplo n.º 14
0
/******************************************************************************
 *  RtlCreateEnvironment		[NTDLL.@]
 */
NTSTATUS WINAPI RtlCreateEnvironment(BOOLEAN inherit, PWSTR* env)
{
    NTSTATUS    nts;

    TRACE("(%u,%p)!\n", inherit, env);

    if (inherit)
    {
        MEMORY_BASIC_INFORMATION        mbi;

        RtlAcquirePebLock();

        nts = NtQueryVirtualMemory(NtCurrentProcess(),
                                   NtCurrentTeb()->Peb->ProcessParameters->Environment,
                                   0, &mbi, sizeof(mbi), NULL);
        if (nts == STATUS_SUCCESS)
        {
            *env = NULL;
            nts = NtAllocateVirtualMemory(NtCurrentProcess(), (void**)env, 0, &mbi.RegionSize, 
                                          MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
            if (nts == STATUS_SUCCESS)
                memcpy(*env, NtCurrentTeb()->Peb->ProcessParameters->Environment, mbi.RegionSize);
            else *env = NULL;
        }
        RtlReleasePebLock();
    }
    else 
    {
        SIZE_T      size = 1;
        PVOID       addr = NULL;
        nts = NtAllocateVirtualMemory(NtCurrentProcess(), &addr, 0, &size,
                                      MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
        if (nts == STATUS_SUCCESS) *env = addr;
    }

    return nts;
}
Ejemplo n.º 15
0
Archivo: server.c Proyecto: iamfil/wine
/***********************************************************************
 *           server_exit_thread
 */
void server_exit_thread( int status )
{
    struct wine_pthread_thread_info info;
    SIZE_T size;
    int fds[4];

    RtlAcquirePebLock();
    RemoveEntryList( &NtCurrentTeb()->TlsLinks );
    RtlReleasePebLock();
    RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->FlsSlots );
    RtlFreeHeap( GetProcessHeap(), 0, NtCurrentTeb()->TlsExpansionSlots );

    info.stack_base  = NtCurrentTeb()->DeallocationStack;
    info.teb_base    = NtCurrentTeb();
    info.teb_sel     = wine_get_fs();
    info.exit_status = status;

    fds[0] = ntdll_get_thread_data()->wait_fd[0];
    fds[1] = ntdll_get_thread_data()->wait_fd[1];
    fds[2] = ntdll_get_thread_data()->reply_fd;
    fds[3] = ntdll_get_thread_data()->request_fd;
    pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, NULL );

    size = 0;
    NtFreeVirtualMemory( GetCurrentProcess(), &info.stack_base, &size, MEM_RELEASE | MEM_SYSTEM );
    info.stack_size = size;

    size = 0;
    NtFreeVirtualMemory( GetCurrentProcess(), &info.teb_base, &size, MEM_RELEASE | MEM_SYSTEM );
    info.teb_size = size;

    close( fds[0] );
    close( fds[1] );
    close( fds[2] );
    close( fds[3] );
    pthread_functions.exit_thread( &info );
}
Ejemplo n.º 16
0
/****************************************************************************
 *		UTRegister (KERNEL32.@)
 */
BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL,
                        LPSTR lpszInitName, LPSTR lpszProcName,
                        FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack,
                        LPVOID lpBuff )
{
    UTINFO *ut;
    HMODULE16 hModule16;
    FARPROC16 target16, init16;
    static BOOL done;

    if (!done)
    {
        LoadLibrary16( "gdi.exe" );
        LoadLibrary16( "user.exe" );
        done = TRUE;
    }

    /* Load 16-bit DLL and get UTProc16 entry point */

    if (   (hModule16 = LoadLibrary16( lpsz16BITDLL )) <= 32
        || (target16  = GetProcAddress16( hModule16, lpszProcName )) == 0 )
        return FALSE;

    /* Allocate UTINFO struct */

    RtlAcquirePebLock();
    if ( (ut = UTFind( hModule )) != NULL )
        ut = NULL;
    else
        ut = UTAlloc( hModule, hModule16, target16, pfnUT32CallBack );
    RtlReleasePebLock();

    if ( !ut )
    {
        FreeLibrary16( hModule16 );
        return FALSE;
    }

    /* Call UTInit16 if present */

    if (     lpszInitName
         && (init16 = GetProcAddress16( hModule16, lpszInitName )) != 0 )
    {
        SEGPTR callback = MapLS( &ut->ut16 );
        SEGPTR segBuff  = MapLS( lpBuff );
        WORD args[4];
        DWORD ret;

        args[3] = SELECTOROF(callback);
        args[2] = OFFSETOF(callback);
        args[1] = SELECTOROF(segBuff);
        args[0] = OFFSETOF(segBuff);
        WOWCallback16Ex( (DWORD)init16, WCB16_PASCAL, sizeof(args), args, &ret );
        UnMapLS( segBuff );
        UnMapLS( callback );
        if (!ret)
        {
            UTUnRegister( hModule );
            return FALSE;
        }
    }

    /* Return 32-bit thunk */

    *ppfn32Thunk = (FARPROC) &ut->ut32;

    return TRUE;
}
Ejemplo n.º 17
0
/******************************************************************************
 *  RtlCreateProcessParameters  [NTDLL.@]
 */
NTSTATUS WINAPI RtlCreateProcessParameters( RTL_USER_PROCESS_PARAMETERS **result,
                                            const UNICODE_STRING *ImagePathName,
                                            const UNICODE_STRING *DllPath,
                                            const UNICODE_STRING *CurrentDirectoryName,
                                            const UNICODE_STRING *CommandLine,
                                            PWSTR Environment,
                                            const UNICODE_STRING *WindowTitle,
                                            const UNICODE_STRING *Desktop,
                                            const UNICODE_STRING *ShellInfo,
                                            const UNICODE_STRING *RuntimeInfo )
{
    static WCHAR empty[] = {0};
    static const UNICODE_STRING empty_str = { 0, sizeof(empty), empty };
    static const UNICODE_STRING null_str = { 0, 0, NULL };

    const RTL_USER_PROCESS_PARAMETERS *cur_params;
    SIZE_T size, total_size;
    void *ptr;
    NTSTATUS status;

    RtlAcquirePebLock();
    cur_params = NtCurrentTeb()->Peb->ProcessParameters;
    if (!DllPath) DllPath = &cur_params->DllPath;
    if (!CurrentDirectoryName)
    {
        if (NtCurrentTeb()->Tib.SubSystemTib)  /* FIXME: hack */
            CurrentDirectoryName = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir.DosPath;
        else
            CurrentDirectoryName = &cur_params->CurrentDirectory.DosPath;
    }
    if (!CommandLine) CommandLine = ImagePathName;
    if (!Environment) Environment = cur_params->Environment;
    if (!WindowTitle) WindowTitle = &empty_str;
    if (!Desktop) Desktop = &empty_str;
    if (!ShellInfo) ShellInfo = &empty_str;
    if (!RuntimeInfo) RuntimeInfo = &null_str;

    size = (sizeof(RTL_USER_PROCESS_PARAMETERS)
            + ImagePathName->MaximumLength
            + DllPath->MaximumLength
            + CurrentDirectoryName->MaximumLength
            + CommandLine->MaximumLength
            + WindowTitle->MaximumLength
            + Desktop->MaximumLength
            + ShellInfo->MaximumLength
            + RuntimeInfo->MaximumLength);

    total_size = size;
    ptr = NULL;
    if ((status = NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, 0, &total_size,
                                           MEM_COMMIT, PAGE_READWRITE )) == STATUS_SUCCESS)
    {
        RTL_USER_PROCESS_PARAMETERS *params = ptr;
        params->AllocationSize = total_size;
        params->Size           = size;
        params->Flags          = PROCESS_PARAMS_FLAG_NORMALIZED;
        params->ConsoleFlags   = cur_params->ConsoleFlags;
        params->Environment    = Environment;
        /* all other fields are zero */

        ptr = params + 1;
        append_unicode_string( &ptr, CurrentDirectoryName, &params->CurrentDirectory.DosPath );
        append_unicode_string( &ptr, DllPath, &params->DllPath );
        append_unicode_string( &ptr, ImagePathName, &params->ImagePathName );
        append_unicode_string( &ptr, CommandLine, &params->CommandLine );
        append_unicode_string( &ptr, WindowTitle, &params->WindowTitle );
        append_unicode_string( &ptr, Desktop, &params->Desktop );
        append_unicode_string( &ptr, ShellInfo, &params->ShellInfo );
        append_unicode_string( &ptr, RuntimeInfo, &params->RuntimeInfo );
        *result = RtlDeNormalizeProcessParams( params );
    }
    RtlReleasePebLock();
    return status;
}
Ejemplo n.º 18
0
/******************************************************************
 *		RtlExpandEnvironmentStrings_U (NTDLL.@)
 *
 */
NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PCWSTR renv, const UNICODE_STRING* us_src,
                                              PUNICODE_STRING us_dst, PULONG plen)
{
    DWORD src_len, len, count, total_size = 1;  /* 1 for terminating '\0' */
    LPCWSTR     env, src, p, var;
    LPWSTR      dst;

    src = us_src->Buffer;
    src_len = us_src->Length / sizeof(WCHAR);
    count = us_dst->MaximumLength / sizeof(WCHAR);
    dst = count ? us_dst->Buffer : NULL;

    if (!renv)
    {
        RtlAcquirePebLock();
        env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
    }
    else env = renv;

    while (src_len)
    {
        if (*src != '%')
        {
            if ((p = memchrW( src, '%', src_len ))) len = p - src;
            else len = src_len;
            var = src;
            src += len;
            src_len -= len;
        }
        else  /* we are at the start of a variable */
        {
            if ((p = memchrW( src + 1, '%', src_len - 1 )))
            {
                len = p - src - 1;  /* Length of the variable name */
                if ((var = ENV_FindVariable( env, src + 1, len )))
                {
                    src += len + 2;  /* Skip the variable name */
                    src_len -= len + 2;
                    len = strlenW(var);
                }
                else
                {
                    var = src;  /* Copy original name instead */
                    len += 2;
                    src += len;
                    src_len -= len;
                }
            }
            else  /* unfinished variable name, ignore it */
            {
                var = src;
                len = src_len;  /* Copy whole string */
                src += len;
                src_len = 0;
            }
        }
        total_size += len;
        if (dst)
        {
            if (count < len) len = count;
            memcpy(dst, var, len * sizeof(WCHAR));
            count -= len;
            dst += len;
        }
    }

    if (!renv) RtlReleasePebLock();

    /* Null-terminate the string */
    if (dst && count) *dst = '\0';

    us_dst->Length = (dst) ? (dst - us_dst->Buffer) * sizeof(WCHAR) : 0;
    if (plen) *plen = total_size * sizeof(WCHAR);

    return (count) ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
}
Ejemplo n.º 19
0
/******************************************************************************
 *  RtlSetEnvironmentVariable		[NTDLL.@]
 */
NTSTATUS WINAPI RtlSetEnvironmentVariable(PWSTR* penv, PUNICODE_STRING name, 
                                          PUNICODE_STRING value)
{
    INT         len, old_size;
    LPWSTR      p, env;
    NTSTATUS    nts = STATUS_VARIABLE_NOT_FOUND;
    MEMORY_BASIC_INFORMATION mbi;

    TRACE("(%p, %s, %s)\n", penv, debugstr_us(name), debugstr_us(value));

    if (!name || !name->Buffer || !name->Length)
        return STATUS_INVALID_PARAMETER_1;

    len = name->Length / sizeof(WCHAR);

    /* variable names can't contain a '=' except as a first character */
    for (p = name->Buffer + 1; p < name->Buffer + len; p++)
        if (*p == '=') return STATUS_INVALID_PARAMETER;

    if (!penv)
    {
        RtlAcquirePebLock();
        env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
    } else env = *penv;

    /* compute current size of environment */
    for (p = env; *p; p += strlenW(p) + 1);
    old_size = p + 1 - env;

    /* Find a place to insert the string */
    for (p = env; *p; p += strlenW(p) + 1)
    {
        if (!strncmpiW(name->Buffer, p, len) && (p[len] == '=')) break;
    }
    if (!value && !*p) goto done;  /* Value to remove doesn't exist */

    /* Realloc the buffer */
    len = value ? len + value->Length / sizeof(WCHAR) + 2 : 0;
    if (*p) len -= strlenW(p) + 1;  /* The name already exists */

    if (len < 0)
    {
        LPWSTR next = p + strlenW(p) + 1;  /* We know there is a next one */
        memmove(next + len, next, (old_size - (next - env)) * sizeof(WCHAR));
    }

    nts = NtQueryVirtualMemory(NtCurrentProcess(), env, 0,
                               &mbi, sizeof(mbi), NULL);
    if (nts != STATUS_SUCCESS) goto done;

    if ((old_size + len) * sizeof(WCHAR) > mbi.RegionSize)
    {
        LPWSTR  new_env;
        SIZE_T  new_size = (old_size + len) * sizeof(WCHAR);

        new_env = NULL;
        nts = NtAllocateVirtualMemory(NtCurrentProcess(), (void**)&new_env, 0,
                                      &new_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
        if (nts != STATUS_SUCCESS) goto done;

        memmove(new_env, env, (p - env) * sizeof(WCHAR));
        assert(len > 0);
        memmove(new_env + (p - env) + len, p, (old_size - (p - env)) * sizeof(WCHAR));
        p = new_env + (p - env);

        RtlDestroyEnvironment(env);
        if (!penv) NtCurrentTeb()->Peb->ProcessParameters->Environment = new_env;
        else *penv = new_env;
    }
    else
    {
        if (len > 0) memmove(p + len, p, (old_size - (p - env)) * sizeof(WCHAR));
    }

    /* Set the new string */
    if (value)
    {
        memcpy( p, name->Buffer, name->Length );
        p += name->Length / sizeof(WCHAR);
        *p++ = '=';
        memcpy( p, value->Buffer, value->Length );
        p[value->Length / sizeof(WCHAR)] = 0;
    }
done:
    if (!penv) RtlReleasePebLock();

    return nts;
}
Ejemplo n.º 20
0
HANDLE
WINAPI
BaseGetNamedObjectDirectory(VOID)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    HANDLE DirHandle, BnoHandle, Token, NewToken;

    if (BaseNamedObjectDirectory) return BaseNamedObjectDirectory;

    if (NtCurrentTeb()->IsImpersonating)
    {
        Status = NtOpenThreadToken(NtCurrentThread(),
                                   TOKEN_IMPERSONATE,
                                   TRUE,
                                   &Token);
        if (!NT_SUCCESS(Status)) return BaseNamedObjectDirectory;

        NewToken = NULL;
        Status = NtSetInformationThread(NtCurrentThread(),
                                        ThreadImpersonationToken,
                                        &NewToken,
                                        sizeof(HANDLE));
        if (!NT_SUCCESS (Status))
        {
            NtClose(Token);
            return BaseNamedObjectDirectory;
        }
    }
    else
    {
        Token = NULL;
    }

    RtlAcquirePebLock();
    if (BaseNamedObjectDirectory) goto Quickie;

    InitializeObjectAttributes(&ObjectAttributes,
                               &BaseStaticServerData->NamedObjectDirectory,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    Status = NtOpenDirectoryObject(&BnoHandle,
                                   DIRECTORY_QUERY |
                                   DIRECTORY_TRAVERSE |
                                   DIRECTORY_CREATE_OBJECT |
                                   DIRECTORY_CREATE_SUBDIRECTORY,
                                   &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        Status = NtOpenDirectoryObject(&DirHandle,
                                       DIRECTORY_TRAVERSE,
                                       &ObjectAttributes);

        if (NT_SUCCESS(Status))
        {
            InitializeObjectAttributes(&ObjectAttributes,
                                       (PUNICODE_STRING)&Restricted,
                                       OBJ_CASE_INSENSITIVE,
                                       DirHandle,
                                       NULL);

            Status = NtOpenDirectoryObject(&BnoHandle,
                                           DIRECTORY_QUERY |
                                           DIRECTORY_TRAVERSE |
                                           DIRECTORY_CREATE_OBJECT |
                                           DIRECTORY_CREATE_SUBDIRECTORY,
                                           &ObjectAttributes);
            NtClose(DirHandle);

        }
    }

    if (NT_SUCCESS(Status)) BaseNamedObjectDirectory = BnoHandle;

Quickie:

    RtlReleasePebLock();

    if (Token)
    {
        NtSetInformationThread(NtCurrentThread(),
                               ThreadImpersonationToken,
                               &Token,
                               sizeof(Token));

        NtClose(Token);
    }

    return BaseNamedObjectDirectory;
}
Ejemplo n.º 21
0
/*
 * @implemented
 */
NTSTATUS NTAPI
RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
			   PUNICODE_STRING ImagePathName,
			   PUNICODE_STRING DllPath,
			   PUNICODE_STRING CurrentDirectory,
			   PUNICODE_STRING CommandLine,
			   PWSTR Environment,
			   PUNICODE_STRING WindowTitle,
			   PUNICODE_STRING DesktopInfo,
			   PUNICODE_STRING ShellInfo,
			   PUNICODE_STRING RuntimeData)
{
   PRTL_USER_PROCESS_PARAMETERS Param = NULL;
   ULONG Length = 0;
   PWCHAR Dest;
   UNICODE_STRING EmptyString;
   HANDLE CurrentDirectoryHandle;
   HANDLE ConsoleHandle;
   ULONG ConsoleFlags;

   DPRINT ("RtlCreateProcessParameters\n");

   RtlAcquirePebLock();

   EmptyString.Length = 0;
   EmptyString.MaximumLength = sizeof(WCHAR);
   EmptyString.Buffer = L"";

   if (RtlpGetMode() == UserMode)
     {
	if (DllPath == NULL)
	  DllPath = &NtCurrentPeb()->ProcessParameters->DllPath;
	if (Environment == NULL)
	  Environment  = NtCurrentPeb()->ProcessParameters->Environment;
	if (CurrentDirectory == NULL)
	  CurrentDirectory = &NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath;
	CurrentDirectoryHandle = NtCurrentPeb()->ProcessParameters->CurrentDirectory.Handle;
	ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
	ConsoleFlags = NtCurrentPeb()->ProcessParameters->ConsoleFlags;
     }
   else
     {
	if (DllPath == NULL)
	  DllPath = &EmptyString;
	if (CurrentDirectory == NULL)
	  CurrentDirectory = &EmptyString;
	CurrentDirectoryHandle = NULL;
	ConsoleHandle = NULL;
	ConsoleFlags = 0;
     }

   if (CommandLine == NULL)
     CommandLine = &EmptyString;
   if (WindowTitle == NULL)
     WindowTitle = &EmptyString;
   if (DesktopInfo == NULL)
     DesktopInfo = &EmptyString;
   if (ShellInfo == NULL)
     ShellInfo = &EmptyString;
   if (RuntimeData == NULL)
     RuntimeData = &EmptyString;

   /* size of process parameter block */
   Length = sizeof(RTL_USER_PROCESS_PARAMETERS);

   /* size of current directory buffer */
   Length += (MAX_PATH * sizeof(WCHAR));

   /* add string lengths */
   Length += ALIGN(DllPath->MaximumLength, sizeof(ULONG));
   Length += ALIGN(ImagePathName->Length + sizeof(WCHAR), sizeof(ULONG));
   Length += ALIGN(CommandLine->Length + sizeof(WCHAR), sizeof(ULONG));
   Length += ALIGN(WindowTitle->MaximumLength, sizeof(ULONG));
   Length += ALIGN(DesktopInfo->MaximumLength, sizeof(ULONG));
   Length += ALIGN(ShellInfo->MaximumLength, sizeof(ULONG));
   Length += ALIGN(RuntimeData->MaximumLength, sizeof(ULONG));

   /* Calculate the required block size */
   Param = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length);
   if (!Param)
     {
	RtlReleasePebLock();
	return STATUS_INSUFFICIENT_RESOURCES;
     }

   DPRINT ("Process parameters allocated\n");

   Param->MaximumLength = Length;
   Param->Length = Length;
   Param->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED;
   Param->Environment = Environment;
   Param->CurrentDirectory.Handle = CurrentDirectoryHandle;
   Param->ConsoleHandle = ConsoleHandle;
   Param->ConsoleFlags = ConsoleFlags;

   Dest = (PWCHAR)(((PBYTE)Param) + sizeof(RTL_USER_PROCESS_PARAMETERS));

   /* copy current directory */
   RtlpCopyParameterString(&Dest,
			   &Param->CurrentDirectory.DosPath,
			   CurrentDirectory,
			   MAX_PATH * sizeof(WCHAR));

   /* make sure the current directory has a trailing backslash */
   if (Param->CurrentDirectory.DosPath.Length > 0)
     {
	ULONG Length;

	Length = Param->CurrentDirectory.DosPath.Length / sizeof(WCHAR);
	if (Param->CurrentDirectory.DosPath.Buffer[Length-1] != L'\\')
	  {
	     Param->CurrentDirectory.DosPath.Buffer[Length] = L'\\';
	     Param->CurrentDirectory.DosPath.Buffer[Length + 1] = 0;
	     Param->CurrentDirectory.DosPath.Length += sizeof(WCHAR);
	  }
     }

   /* copy dll path */
   RtlpCopyParameterString(&Dest,
			   &Param->DllPath,
			   DllPath,
			   0);

   /* copy image path name */
   RtlpCopyParameterString(&Dest,
			   &Param->ImagePathName,
			   ImagePathName,
			   ImagePathName->Length + sizeof(WCHAR));

   /* copy command line */
   RtlpCopyParameterString(&Dest,
			   &Param->CommandLine,
			   CommandLine,
			   CommandLine->Length + sizeof(WCHAR));

   /* copy title */
   RtlpCopyParameterString(&Dest,
			   &Param->WindowTitle,
			   WindowTitle,
			   0);

   /* copy desktop */
   RtlpCopyParameterString(&Dest,
			   &Param->DesktopInfo,
			   DesktopInfo,
			   0);

   /* copy shell info */
   RtlpCopyParameterString(&Dest,
			   &Param->ShellInfo,
			   ShellInfo,
			   0);

   /* copy runtime info */
   RtlpCopyParameterString(&Dest,
			   &Param->RuntimeData,
			   RuntimeData,
			   0);

   RtlDeNormalizeProcessParams(Param);
   *ProcessParameters = Param;
   RtlReleasePebLock();

   return STATUS_SUCCESS;
}
Ejemplo n.º 22
0
NTSTATUS
RtlCreateProcessParameters(
    OUT PRTL_USER_PROCESS_PARAMETERS *pProcessParameters,
    IN PUNICODE_STRING ImagePathName,
    IN PUNICODE_STRING DllPath OPTIONAL,
    IN PUNICODE_STRING CurrentDirectory OPTIONAL,
    IN PUNICODE_STRING CommandLine OPTIONAL,
    IN PVOID Environment OPTIONAL,
    IN PUNICODE_STRING WindowTitle OPTIONAL,
    IN PUNICODE_STRING DesktopInfo OPTIONAL,
    IN PUNICODE_STRING ShellInfo OPTIONAL,
    IN PUNICODE_STRING RuntimeData OPTIONAL
    )

/*++

Routine Description:

    This function formats NT style RTL_USER_PROCESS_PARAMETERS
    record.  The record is self-contained in a single block of memory
    allocated by this function.  The allocation method is opaque and
    thus the record must be freed by calling the
    RtlDestroyProcessParameters function.

    The process parameters record is created in a de-normalized form,
    thus making it suitable for passing to the RtlCreateUserProcess
    function.  It is expected that the caller will fill in additional
    fields in the process parameters record after this function returns,
    but prior to calling RtlCreateUserProcess.

Arguments:

    pProcessParameters - Pointer to a variable that will receive the address
        of the process parameter structure created by this routine.  The
        memory for the structure is allocated in an opaque manner and must
        be freed by calling RtlDestroyProcessParameters.

    ImagePathName - Required parameter that is the fully qualified NT
        path name of the image file that will be used to create the process
        that will received these parameters.

    DllPath - An optional parameter that is an NT String variable pointing
        to the search path the NT Loader is to use in the target process
        when searching for Dll modules.  If not specified, then the Dll
        search path is filled in from the current process's Dll search
        path.

    CurrentDirectory - An optional parameter that is an NT String variable
        pointing to the default directory string for the target process.
        If not specified, then the current directory string is filled in
        from the current process's current directory string.

    CommandLine - An optional parameter that is an NT String variable that
        will be passed to the target process as its command line.  If not
        specified, then the command line passed to the target process will
        be a null string.

    Environment - An optional parameter that is an opaque pointer to an
        environment variable block of the type created by
        RtlCreateEnvironment routine.  If not specified, then the target
        process will receive a copy of the calling process's environment
        variable block.

    WindowTitle - An optional parameter that is an NT String variable that
        points to the title string the target process is to use for its
        main window.  If not specified, then a null string will be passed
        to the target process as its default window title.

    DesktopInfo - An optional parameter that is an NT String variable that
        contains uninterpreted data that is passed as is to the target
        process.  If not specified, the target process will receive a
        pointer to an empty string.

    ShellInfo - An optional parameter that is an NT String variable that
        contains uninterpreted data that is passed as is to the target
        process.  If not specified, the target process will receive a
        pointer to an empty string.

    RuntimeData - An optional parameter that is an NT String variable that
        contains uninterpreted data that is passed as is to the target
        process.  If not specified, the target process will receive a
        pointer to an empty string.

Return Value:

    STATUS_SUCCESS - The process parameters is De-Normalized and
        contains entries for each of the specified argument and variable
        strings.

    STATUS_BUFFER_TOO_SMALL - The specified process parameters buffer is
        too small to contain the argument and environment strings. The value
        of ProcessParameters->Length is modified to contain the buffer
        size needed to contain the argument and variable strings.

--*/

{
    PRTL_USER_PROCESS_PARAMETERS p;
    NTSTATUS Status;
    ULONG ByteCount;
    PWSTR pDst;
    PPEB Peb;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    HANDLE CurDirHandle;
    BOOLEAN PebLockAcquired = FALSE;

    //
    // Acquire the Peb Lock for the duration while we copy information out
    // of it.
    //

    Peb = NtCurrentPeb();
    ProcessParameters = Peb->ProcessParameters;

    Status = STATUS_SUCCESS;
    p = NULL;
    CurDirHandle = NULL;
    try {
        //
        //  Validate input parameters
        //

#define VALIDATE_STRING_PARAMETER(_x) \
    do { \
        ASSERT(ARGUMENT_PRESENT((_x))); \
        if (!ARGUMENT_PRESENT((_x))) { \
            Status = STATUS_INVALID_PARAMETER; \
            leave; \
        } \
        if (ARGUMENT_PRESENT((_x))) { \
            ASSERT((_x)->MaximumLength >= (_x)->Length); \
            ASSERT(((_x)->Length == 0) || ((_x)->Buffer != NULL)); \
            if (((_x)->MaximumLength < (_x)->Length) || \
                (((_x)->Length != 0) && ((_x)->Buffer == NULL))) { \
                Status = STATUS_INVALID_PARAMETER; \
                leave; \
            } \
        } \
    } while (0)

#define VALIDATE_OPTIONAL_STRING_PARAMETER(_x) \
    do { \
        if (ARGUMENT_PRESENT((_x))) { \
            ASSERT((_x)->MaximumLength >= (_x)->Length); \
            ASSERT(((_x)->Length == 0) || ((_x)->Buffer != NULL)); \
            if (((_x)->MaximumLength < (_x)->Length) || \
                (((_x)->Length != 0) && ((_x)->Buffer == NULL))) { \
                Status = STATUS_INVALID_PARAMETER; \
                leave; \
            } \
        } \
    } while (0)

        VALIDATE_STRING_PARAMETER (ImagePathName);
        VALIDATE_OPTIONAL_STRING_PARAMETER (DllPath);
        VALIDATE_OPTIONAL_STRING_PARAMETER (CurrentDirectory);
        VALIDATE_OPTIONAL_STRING_PARAMETER (CommandLine);
        VALIDATE_OPTIONAL_STRING_PARAMETER (WindowTitle);
        VALIDATE_OPTIONAL_STRING_PARAMETER (DesktopInfo);
        VALIDATE_OPTIONAL_STRING_PARAMETER (ShellInfo);
        VALIDATE_OPTIONAL_STRING_PARAMETER (RuntimeData);

#undef VALIDATE_STRING_PARAMETER
#undef VALIDATE_OPTIONAL_STRING_PARAMETER

        if (!ARGUMENT_PRESENT (CommandLine)) {
            CommandLine = ImagePathName;
        }

        if (!ARGUMENT_PRESENT (WindowTitle)) {
            WindowTitle = (PUNICODE_STRING)&NullString;
        }

        if (!ARGUMENT_PRESENT (DesktopInfo)) {
            DesktopInfo = (PUNICODE_STRING)&NullString;
        }

        if (!ARGUMENT_PRESENT (ShellInfo)) {
            ShellInfo = (PUNICODE_STRING)&NullString;
        }

        if (!ARGUMENT_PRESENT (RuntimeData)) {
            RuntimeData = (PUNICODE_STRING)&NullString;
        }

        //
        // Determine size need to contain the process parameter record
        // structure and all of the strings it will point to.  Each string
        // will be aligned on a ULONG byte boundary.
        // We do the ones we can outside of the peb lock.
        //

        ByteCount = sizeof (*ProcessParameters);
        ByteCount += ROUND_UP (DOS_MAX_PATH_LENGTH*2,        sizeof( ULONG ) );
        ByteCount += ROUND_UP (ImagePathName->Length + sizeof(UNICODE_NULL),    sizeof( ULONG ) );
        ByteCount += ROUND_UP (CommandLine->Length + sizeof(UNICODE_NULL),      sizeof( ULONG ) );
        ByteCount += ROUND_UP (WindowTitle->MaximumLength,   sizeof( ULONG ) );
        ByteCount += ROUND_UP (DesktopInfo->MaximumLength,   sizeof( ULONG ) );
        ByteCount += ROUND_UP (ShellInfo->MaximumLength,     sizeof( ULONG ) );
        ByteCount += ROUND_UP (RuntimeData->MaximumLength,   sizeof( ULONG ) );

        PebLockAcquired = TRUE;
        RtlAcquirePebLock ();

        //
        // For optional pointer parameters, default them to point to their
        // corresponding field in the current process's process parameter
        // structure or to a null string.
        //

        if (!ARGUMENT_PRESENT (DllPath)) {
            DllPath = &ProcessParameters->DllPath;
        }

        if (!ARGUMENT_PRESENT (CurrentDirectory)) {

            if (ProcessParameters->CurrentDirectory.Handle) {
                CurDirHandle = (HANDLE)((ULONG_PTR)ProcessParameters->CurrentDirectory.Handle & ~OBJ_HANDLE_TAGBITS);
                CurDirHandle = (HANDLE)((ULONG_PTR)CurDirHandle | RTL_USER_PROC_CURDIR_INHERIT);
            }
            CurrentDirectory = &ProcessParameters->CurrentDirectory.DosPath;
        } else {
            ASSERT(CurrentDirectory->MaximumLength >= CurrentDirectory->Length);
            ASSERT((CurrentDirectory->Length == 0) || (CurrentDirectory->Buffer != NULL));

            if (ProcessParameters->CurrentDirectory.Handle) {
                CurDirHandle = (HANDLE)((ULONG_PTR)ProcessParameters->CurrentDirectory.Handle & ~OBJ_HANDLE_TAGBITS);
                CurDirHandle = (HANDLE)((ULONG_PTR)CurDirHandle | RTL_USER_PROC_CURDIR_CLOSE);
            }
        }


        if (!ARGUMENT_PRESENT (Environment)) {
            Environment = ProcessParameters->Environment;
        }

        ByteCount += ROUND_UP (DllPath->MaximumLength,       sizeof( ULONG ) );

        //
        // Allocate memory for the process parameter record.
        //
        p = RtlAllocateHeap (RtlProcessHeap (), 0, ByteCount);

        if (p == NULL) {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            __leave;
        }

        RtlZeroMemory (p, sizeof (*p));

        p->MaximumLength = ByteCount;
        p->Length = ByteCount;
        p->Flags = RTL_USER_PROC_PARAMS_NORMALIZED;
        p->DebugFlags = 0;
        p->Environment = Environment;
        p->CurrentDirectory.Handle = CurDirHandle;

        //
        // Inherits ^C inhibit information
        //

        p->ConsoleFlags = ProcessParameters->ConsoleFlags;

        pDst = (PWSTR)(p + 1);
        RtlpCopyProcString (&pDst,
                            &p->CurrentDirectory.DosPath,
                            CurrentDirectory,
                            DOS_MAX_PATH_LENGTH*2);

        RtlpCopyProcString (&pDst, &p->DllPath, DllPath, 0);
        RtlpCopyProcString (&pDst, &p->ImagePathName, ImagePathName, ImagePathName->Length + sizeof (UNICODE_NULL));
        if (CommandLine->Length == CommandLine->MaximumLength) {
            RtlpCopyProcString (&pDst, &p->CommandLine, CommandLine, 0);
        } else {
            RtlpCopyProcString (&pDst, &p->CommandLine, CommandLine, CommandLine->Length + sizeof (UNICODE_NULL));
        }

        RtlpCopyProcString (&pDst, &p->WindowTitle, WindowTitle, 0);
        RtlpCopyProcString (&pDst, &p->DesktopInfo, DesktopInfo, 0);
        RtlpCopyProcString (&pDst, &p->ShellInfo,   ShellInfo, 0);
        if (RuntimeData->Length != 0) {
            RtlpCopyProcString (&pDst, &p->RuntimeData, RuntimeData, 0);
        }
        *pProcessParameters = RtlDeNormalizeProcessParams (p);
        p = NULL;
    } finally {
        if (PebLockAcquired) {
            RtlReleasePebLock();
        }

        if (AbnormalTermination ()) {
            Status = STATUS_ACCESS_VIOLATION;
        }

        if (p != NULL) {
            RtlDestroyProcessParameters (p);
        }

    }

    return Status;
}
Ejemplo n.º 23
0
/*
 * @implemented
 */
VOID
WINAPI
GetStartupInfoA(LPSTARTUPINFOA lpStartupInfo)
{
    PRTL_USER_PROCESS_PARAMETERS Params;
    ANSI_STRING AnsiString;

    if (lpStartupInfo == NULL)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return;
    }

    Params = NtCurrentPeb ()->ProcessParameters;

    RtlAcquirePebLock ();

    /* FIXME - not thread-safe */
    if (lpLocalStartupInfo == NULL)
    {
        /* create new local startup info (ansi) */
        lpLocalStartupInfo = RtlAllocateHeap(RtlGetProcessHeap(),
                                             0,
                                             sizeof(STARTUPINFOA));
        if (lpLocalStartupInfo == NULL)
        {
            RtlReleasePebLock();
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return;
        }

        lpLocalStartupInfo->cb = sizeof(STARTUPINFOA);

        /* copy window title string */
        RtlUnicodeStringToAnsiString(&AnsiString,
                                     &Params->WindowTitle,
                                     TRUE);
        lpLocalStartupInfo->lpTitle = AnsiString.Buffer;

        /* copy desktop info string */
        RtlUnicodeStringToAnsiString(&AnsiString,
                                     &Params->DesktopInfo,
                                     TRUE);
        lpLocalStartupInfo->lpDesktop = AnsiString.Buffer;

        /* copy shell info string */
        RtlUnicodeStringToAnsiString(&AnsiString,
                                     &Params->ShellInfo,
                                     TRUE);
        lpLocalStartupInfo->lpReserved = AnsiString.Buffer;

        lpLocalStartupInfo->dwX = Params->StartingX;
        lpLocalStartupInfo->dwY = Params->StartingY;
        lpLocalStartupInfo->dwXSize = Params->CountX;
        lpLocalStartupInfo->dwYSize = Params->CountY;
        lpLocalStartupInfo->dwXCountChars = Params->CountCharsX;
        lpLocalStartupInfo->dwYCountChars = Params->CountCharsY;
        lpLocalStartupInfo->dwFillAttribute = Params->FillAttribute;
        lpLocalStartupInfo->dwFlags = Params->WindowFlags;
        lpLocalStartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
        lpLocalStartupInfo->cbReserved2 = Params->RuntimeData.Length;
        lpLocalStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;

        lpLocalStartupInfo->hStdInput = Params->StandardInput;
        lpLocalStartupInfo->hStdOutput = Params->StandardOutput;
        lpLocalStartupInfo->hStdError = Params->StandardError;
    }

    RtlReleasePebLock();

    /* copy local startup info data to external startup info */
    memcpy(lpStartupInfo,
           lpLocalStartupInfo,
           sizeof(STARTUPINFOA));
}
Ejemplo n.º 24
0
/*
 * @implemented
 */
NTSTATUS
NTAPI
RtlCreateEnvironment(
    BOOLEAN Inherit,
    PWSTR *OutEnvironment)
{
    MEMORY_BASIC_INFORMATION MemInfo;
    PVOID CurrentEnvironment, NewEnvironment = NULL;
    NTSTATUS Status = STATUS_SUCCESS;
    SIZE_T RegionSize = PAGE_SIZE;

    /* Check if we should inherit the current environment */
    if (Inherit)
    {
        /* In this case we need to lock the PEB */
        RtlAcquirePebLock();

        /* Get a pointer to the current Environment and check if it's not NULL */
        CurrentEnvironment = NtCurrentPeb()->ProcessParameters->Environment;
        if (CurrentEnvironment != NULL)
        {
            /* Query the size of the current environment allocation */
            Status = NtQueryVirtualMemory(NtCurrentProcess(),
                                          CurrentEnvironment,
                                          MemoryBasicInformation,
                                          &MemInfo,
                                          sizeof(MEMORY_BASIC_INFORMATION),
                                          NULL);
            if (!NT_SUCCESS(Status))
            {
                RtlReleasePebLock();
                *OutEnvironment = NULL;
                return Status;
            }

            /* Allocate a new region of the same size */
            RegionSize = MemInfo.RegionSize;
            Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                             &NewEnvironment,
                                             0,
                                             &RegionSize,
                                             MEM_RESERVE | MEM_COMMIT,
                                             PAGE_READWRITE);
            if (!NT_SUCCESS(Status))
            {
                RtlReleasePebLock();
                *OutEnvironment = NULL;
                return Status;
            }

            /* Copy the current environment */
            RtlCopyMemory(NewEnvironment,
                          CurrentEnvironment,
                          MemInfo.RegionSize);
        }

        /* We are done with the PEB, release the lock */
        RtlReleasePebLock ();
    }

    /* Check if we still need an environment */
    if (NewEnvironment == NULL)
    {
        /* Allocate a new environment */
        Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                         &NewEnvironment,
                                         0,
                                         &RegionSize,
                                         MEM_RESERVE | MEM_COMMIT,
                                         PAGE_READWRITE);
        if (NT_SUCCESS(Status))
        {
            RtlZeroMemory(NewEnvironment, RegionSize);
        }
    }

    *OutEnvironment = NewEnvironment;

    return Status;
}
Ejemplo n.º 25
0
/*
 * @implemented
 */
NTSTATUS NTAPI
RtlSetEnvironmentVariable(PWSTR *Environment,
                          PUNICODE_STRING Name,
                          PUNICODE_STRING Value)
{
   MEMORY_BASIC_INFORMATION mbi;
   UNICODE_STRING var;
   size_t hole_len, new_len, env_len = 0;
   WCHAR *new_env = 0, *env_end = 0, *wcs, *env, *val = 0, *tail = 0, *hole = 0;
   PWSTR head = NULL;
   SIZE_T size = 0, new_size;
   LONG f = 1;
   NTSTATUS Status = STATUS_SUCCESS;

   DPRINT("RtlSetEnvironmentVariable(Environment %p Name %wZ Value %wZ)\n",
          Environment, Name, Value);

   /* Variable name must not be empty */
   if (Name->Length < sizeof(WCHAR))
      return STATUS_INVALID_PARAMETER;

   /* Variable names can't contain a '=' except as a first character. */
   for (wcs = Name->Buffer + 1;
        wcs < Name->Buffer + (Name->Length / sizeof(WCHAR));
        wcs++)
   {
      if (*wcs == L'=')
          return STATUS_INVALID_PARAMETER;
   }

   if (Environment)
   {
      env = *Environment;
   }
   else
   {
      RtlAcquirePebLock();
      env = NtCurrentPeb()->ProcessParameters->Environment;
   }

   if (env)
   {
      /* get environment length */
      wcs = env_end = env;
      do
      {
         env_end += wcslen(env_end) + 1;
      }
      while (*env_end);
      env_end++;
      env_len = env_end - env;
      DPRINT("environment length %lu characters\n", env_len);

      /* find where to insert */
      while (*wcs)
      {
         var.Buffer = wcs++;
         wcs = wcschr(wcs, L'=');
         if (wcs == NULL)
         {
            wcs = var.Buffer + wcslen(var.Buffer);
         }
         if (*wcs)
         {
            var.Length = (USHORT)(wcs - var.Buffer) * sizeof(WCHAR);
            var.MaximumLength = var.Length;
            val = ++wcs;
            wcs += wcslen(wcs);
            f = RtlCompareUnicodeString(&var, Name, TRUE);
            if (f >= 0)
            {
               if (f) /* Insert before found */
               {
                  hole = tail = var.Buffer;
               }
               else /* Exact match */
               {
                  head = var.Buffer;
                  tail = ++wcs;
                  hole = val;
               }
               goto found;
            }
         }
         wcs++;
      }
      hole = tail = wcs; /* Append to environment */
   }

found:
   if (Value != NULL && Value->Buffer != NULL)
   {
      hole_len = tail - hole;
      /* calculate new environment size */
      new_size = Value->Length + sizeof(WCHAR);
      /* adding new variable */
      if (f)
         new_size += Name->Length + sizeof(WCHAR);
      new_len = new_size / sizeof(WCHAR);
      if (hole_len < new_len)
      {
         /* enlarge environment size */
         /* check the size of available memory */
         new_size += (env_len - hole_len) * sizeof(WCHAR);
         new_size = ROUND_UP(new_size, PAGE_SIZE);
         mbi.RegionSize = 0;
         DPRINT("new_size %lu\n", new_size);

         if (env)
         {
            Status = NtQueryVirtualMemory(NtCurrentProcess(),
                                          env,
                                          MemoryBasicInformation,
                                          &mbi,
                                          sizeof(MEMORY_BASIC_INFORMATION),
                                          NULL);
            if (!NT_SUCCESS(Status))
            {
               if (Environment == NULL)
               {
                  RtlReleasePebLock();
               }
               return(Status);
            }
         }

         if (new_size > mbi.RegionSize)
         {
            /* reallocate memory area */
            Status = NtAllocateVirtualMemory(NtCurrentProcess(),
                                             (PVOID)&new_env,
                                             0,
                                             &new_size,
                                             MEM_RESERVE | MEM_COMMIT,
                                             PAGE_READWRITE);
            if (!NT_SUCCESS(Status))
            {
               if (Environment == NULL)
               {
                  RtlReleasePebLock();
               }
               return(Status);
            }

            if (env)
            {
               memmove(new_env,
                       env,
                       (hole - env) * sizeof(WCHAR));
               hole = new_env + (hole - env);
            }
            else
            {
               /* absolutely new environment */
               tail = hole = new_env;
               *hole = 0;
               env_end = hole + 1;
            }
         }
      }

      /* move tail */
      memmove (hole + new_len, tail, (env_end - tail) * sizeof(WCHAR));

      if (new_env)
      {
         /* we reallocated environment, let's free the old one */
         if (Environment)
            *Environment = new_env;
         else
            NtCurrentPeb()->ProcessParameters->Environment = new_env;

         if (env)
         {
            size = 0;
            NtFreeVirtualMemory(NtCurrentProcess(),
                                (PVOID)&env,
                                &size,
                                MEM_RELEASE);
         }
      }

      /* and now copy given stuff */
      if (f)
      {
         /* copy variable name and '=' character */
         memmove(hole,
                 Name->Buffer,
                 Name->Length);
         hole += Name->Length / sizeof(WCHAR);
         *hole++ = L'=';
      }

      /* copy value */
      memmove(hole,
              Value->Buffer,
              Value->Length);
      hole += Value->Length / sizeof(WCHAR);
      *hole = 0;
   }
   else
   {
      /* remove the environment variable */
      if (f == 0)
      {
         memmove(head,
                 tail,
                 (env_end - tail) * sizeof(WCHAR));
      }
   }

   if (Environment == NULL)
   {
      RtlReleasePebLock();
   }

   return(Status);
}
Ejemplo n.º 26
0
/*
 * @implemented
 */
NTSTATUS NTAPI
RtlQueryEnvironmentVariable_U(PWSTR Environment,
                              PUNICODE_STRING Name,
                              PUNICODE_STRING Value)
{
   NTSTATUS Status;
   PWSTR wcs;
   UNICODE_STRING var;
   PWSTR val;
   BOOLEAN SysEnvUsed = FALSE;

   DPRINT("RtlQueryEnvironmentVariable_U Environment %p Variable %wZ Value %p\n",
          Environment, Name, Value);

   if (Environment == NULL)
   {
      PPEB Peb = RtlGetCurrentPeb();
      if (Peb) {
          Environment = Peb->ProcessParameters->Environment;
          SysEnvUsed = TRUE;
      }
   }

   if (Environment == NULL)
   {
      return(STATUS_VARIABLE_NOT_FOUND);
   }

   Value->Length = 0;
   if (SysEnvUsed)
      RtlAcquirePebLock();

   wcs = Environment;
   DPRINT("Starting search at :%p\n", wcs);
   while (*wcs)
   {
      var.Buffer = wcs++;
      wcs = wcschr(wcs, L'=');
      if (wcs == NULL)
      {
         wcs = var.Buffer + wcslen(var.Buffer);
         DPRINT("Search at :%S\n", wcs);
      }
      if (*wcs)
      {
         var.Length = var.MaximumLength = (USHORT)(wcs - var.Buffer) * sizeof(WCHAR);
         val = ++wcs;
         wcs += wcslen(wcs);
         DPRINT("Search at :%S\n", wcs);

         if (RtlEqualUnicodeString(&var, Name, TRUE))
         {
            Value->Length = (USHORT)(wcs - val) * sizeof(WCHAR);
            if (Value->Length <= Value->MaximumLength)
            {
               memcpy(Value->Buffer, val,
                      min(Value->Length + sizeof(WCHAR), Value->MaximumLength));
               DPRINT("Value %S\n", val);
               DPRINT("Return STATUS_SUCCESS\n");
               Status = STATUS_SUCCESS;
            }
            else
            {
               DPRINT("Return STATUS_BUFFER_TOO_SMALL\n");
               Status = STATUS_BUFFER_TOO_SMALL;
            }

            if (SysEnvUsed)
               RtlReleasePebLock();

            return(Status);
         }
      }
      wcs++;
   }

   if (SysEnvUsed)
      RtlReleasePebLock();

   DPRINT("Return STATUS_VARIABLE_NOT_FOUND: %wZ\n", Name);
   return(STATUS_VARIABLE_NOT_FOUND);
}