Esempio n. 1
0
bool Platform::GetCurrentEnvironment(EnvironmentBlock &env) {
  WCHAR *envStrings = GetEnvironmentStringsW();
  WCHAR *oldEnvStrings = envStrings;
  if (envStrings == nullptr)
    return false;

  while (*envStrings) {
    std::string envStr;
    envStr = WideToNarrowString(envStrings);

    size_t equal = envStr.find('=');
    DS2ASSERT(equal != std::string::npos);

    // Some environment values can start with '=' for MS-DOS compatibility.
    // Ignore these values.
    if (equal != 0)
      env[envStr.substr(0, equal)] = envStr.substr(equal + 1);

    envStrings += wcslen(envStrings) + 1;
  }

  FreeEnvironmentStringsW(oldEnvStrings);

  return true;
}
Esempio n. 2
0
        void fix_env(char **&en)
        {
            static char *dummy = 0;
            en = &dummy;
            wchar_t *wstrings = GetEnvironmentStringsW();
            if(!wstrings)
                return;
            try {
                wchar_t *wstrings_end = 0;
                int count = 0;
                for(wstrings_end = wstrings;*wstrings_end;wstrings_end+=wcslen(wstrings_end)+1)
                        count++;
                if(env_.convert(wstrings,wstrings_end)) {
                    envp_.resize(count+1,0);
                    char *p=env_.c_str();
                    int pos = 0;
                    for(int i=0;i<count;i++) {
                        if(*p!='=')
                            envp_[pos++] = p;
                        p+=strlen(p)+1;
                    }
                    en = &envp_[0];
                }
            }
            catch(...) {
                FreeEnvironmentStringsW(wstrings);
                throw;
            }
            FreeEnvironmentStringsW(wstrings);

        }
// pequeña prueba
int main()
{
  HWND hwnd = FindWindow( 0, "Solitaire" ) ;
  assert( hwnd ) ;
  DWORD procid = 0 ;
  GetWindowThreadProcessId( hwnd, &procid ) ;
  assert( procid ) ;
  
  //Una manera de tener mas presicion al abrir el proceso. 
  //Practicamente se suman los flags
  DWORD amask = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ ;
  
  HANDLE hproc = OpenProcess( amask, 0, procid ) ;
  assert( hproc ) ;
  
  wchar_t* env = GetEnvironmentStringsW( hproc ) ;

  wchar_t* pwstr = env  ;
  do
  {
    std::cout << pwstr << '\n' ;
    pwstr += wcslen(pwstr) + 1 ; //strlen
  }while( *pwstr ) ;

  delete[] env  ;
}
Esempio n. 4
0
	DKLIB_API DKMap<DKString, DKString> DKProcessEnvironments(void)
	{
		DKMap<DKString, DKString> env;
		LPWSTR str = (LPWSTR)GetEnvironmentStringsW();
		if (str)
		{
			while (*str)
			{
				/* key=value */
				DKString tmp(str);
				long i = tmp.Find(L'=');
				if (i > 0)
				{
					DKString key = tmp.Left(i);
					DKString val = tmp.Right(i+1);

					env.Update(key, val);
				}
				
				size_t len = wcslen(str);
				str += len + 1;
			}
			FreeEnvironmentStringsW((LPWCH)str);
		}
		return env;
	}
Esempio n. 5
0
void CALLBACK Export( HWND, HINSTANCE, LPTSTR lpCmdLine, int )
{
    if( !lpCmdLine )
        ExitProcess( 0 );
    Handle onp( CreateFile( lpCmdLine, GENERIC_WRITE,
                FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0 ) );

    if( !onp || onp == INVALID_HANDLE_VALUE )
        ExitProcess( 0 );
    
    wchar_t* env = GetEnvironmentStringsW();
    int i;
    for( i = 0; *(int*)(env + i); i++ );

    i *= sizeof(*env);
    i += 2 * sizeof(*env);

    DWORD written;

    WriteFile( onp, env, i, &written, 0 );

    FreeEnvironmentStringsW( env );

    return;
}
Esempio n. 6
0
//------------------------------------------------------------------------------
static void capture_env(env_block_t* block)
{
    void* env;
    const wchar_t* c;
    void* data;
    int size;

    env = GetEnvironmentStringsW();

    size = 0;
    c = (const wchar_t*)env;
    while (1)
    {
        if (*((const int*)(c)) == 0)
        {
            size += 4;
            break;
        }

        size += 2;
        ++c;
    }

    data = malloc(size);
    memcpy(data, env, size);

    block->data = data;
    block->size = size;

    FreeEnvironmentStringsW(env);
}
Esempio n. 7
0
extern "C" LPVOID WINAPI dllGetEnvironmentStringsW()
{
#ifdef TARGET_WINDOWS
  return GetEnvironmentStringsW();
#else  
  return 0;
#endif
}
Esempio n. 8
0
    static void
inc_cRefThisDLL()
{
#ifdef FEAT_GETTEXT
    if (g_cRefThisDll == 0) {
	dyn_gettext_load();
	oldenv = GetEnvironmentStringsW();
    }
#endif
    InterlockedIncrement((LPLONG)&g_cRefThisDll);
}
Esempio n. 9
0
bool OOBase::Environment::get_current(env_table_t& tabEnv)
{
	wchar_t* env = GetEnvironmentStringsW();
	if (!env)
		return GetLastError() == ERROR_SUCCESS;

	int err = process_block(env,tabEnv);

	FreeEnvironmentStringsW(env);

	return (err == ERROR_SUCCESS);
}
Result<Environment> Environment::CreateForCurrentProcess(Trace& trace)
{
	trace < L"Environment::CreateForCurrentProcess";
	auto environment = GetEnvironmentStringsW();
	Environment newEnvironment;
	try
	{
		newEnvironment.CreateVariableMap(environment, trace);
	}
	catch(...)
	{		
	}	

	FreeEnvironmentStringsW(environment);
	return newEnvironment;
}
Esempio n. 11
0
void runner::restore_original_environment(const runner::env_vars_list_t& original) const
{
    auto curr_vars = read_environment(GetEnvironmentStringsW());

    for (auto i = original.cbegin(); i != original.cend(); ++i)
    {
        SetEnvironmentVariableA(i->first.c_str(), i->second.c_str());
    }

    for (auto i = curr_vars.cbegin(); i != curr_vars.cend(); ++i)
    {
        if (std::find(original.cbegin(), original.cend(), *i) == original.cend())
        {
            SetEnvironmentVariableA(i->first.c_str(), NULL);
        }
    }
}
Esempio n. 12
0
char*
win_build_environment(char* new_env)
{
    if (new_env == NULL) {
	return NULL;
    } else {
	WCHAR *tmp, *merged, *tmp_new;

	tmp_new = (WCHAR *) new_env;
	
	erts_rwmtx_rlock(&environ_rwmtx);
	tmp = GetEnvironmentStringsW();
	merged = merge_environment(tmp, tmp_new);

	FreeEnvironmentStringsW(tmp);
	erts_rwmtx_runlock(&environ_rwmtx);
	return (char *) merged;
    }
}
Esempio n. 13
0
/* Returns a Windows style environment block, discarding final trailing NUL */
JNIEXPORT jstring JNICALL
Java_java_lang_ProcessEnvironment_environmentBlock(JNIEnv *env, jclass klass)
{
    int i;
    jstring envblock;
    jchar *blockW = (jchar *) GetEnvironmentStringsW();
    if (blockW == NULL)
        return environmentBlock9x(env);

    /* Don't search for "\u0000\u0000", since an empty environment
       block may legitimately consist of a single "\u0000".  */
    for (i = 0; blockW[i];)
        while (blockW[i++])
            ;

    envblock = (*env)->NewString(env, blockW, i);
    FreeEnvironmentStringsW(blockW);
    return envblock;
}
Esempio n. 14
0
runner::env_vars_list_t runner::set_environment_for_process() const
{
    auto curr_vars = read_environment(GetEnvironmentStringsW());

    if (options.environmentMode == "user-default")
    {
        LPVOID envBlock = NULL;

        CreateEnvironmentBlock(&envBlock, NULL, FALSE);

        auto default_vars = read_environment((WCHAR*)envBlock);

        DestroyEnvironmentBlock(envBlock);

        for (auto i = default_vars.cbegin(); i != default_vars.cend(); ++i)
        {
            SetEnvironmentVariableA(i->first.c_str(), i->second.c_str());
        }

        for (auto i = curr_vars.cbegin(); i != curr_vars.cend(); ++i)
        {
            if (std::find(default_vars.cbegin(), default_vars.cend(), *i) == default_vars.cend())
            {
                SetEnvironmentVariableA(i->first.c_str(), NULL);
            }
        }
    }
    else if (options.environmentMode == "clear")
    {
        for (auto i = curr_vars.cbegin(); i != curr_vars.cend(); ++i)
        {
            SetEnvironmentVariableA(i->first.c_str(), NULL);
        }
    }

    for (auto i = options.environmentVars.cbegin(); i != options.environmentVars.cend(); ++i) {
        SetEnvironmentVariableA(i->first.c_str(), i->second.c_str());
    }

    return curr_vars;
}
Esempio n. 15
0
QProcessEnvironment QProcessEnvironment::systemEnvironment()
{
    QProcessEnvironment env;
    // Calls to setenv() affect the low-level environment as well.
    // This is not the case the other way round.
    if (wchar_t *envStrings = GetEnvironmentStringsW()) {
        for (const wchar_t *entry = envStrings; *entry; ) {
            const int entryLen = int(wcslen(entry));
            // + 1 to permit magic cmd variable names starting with =
            if (const wchar_t *equal = wcschr(entry + 1, L'=')) {
                int nameLen = equal - entry;
                QString name = QString::fromWCharArray(entry, nameLen);
                QString value = QString::fromWCharArray(equal + 1, entryLen - nameLen - 1);
                env.d->hash.insert(QProcessEnvironmentPrivate::Key(name), value);
            }
            entry += entryLen + 1;
        }
        FreeEnvironmentStringsW(envStrings);
    }
    return env;
}
Esempio n. 16
0
QProcessEnvironment QProcessEnvironment::systemEnvironment()
{
    QProcessEnvironment env;
#if !defined(Q_OS_WINCE)
    // Calls to setenv() affect the low-level environment as well.
    // This is not the case the other way round.
    if (wchar_t *envStrings = GetEnvironmentStringsW()) {
        for (const wchar_t *entry = envStrings; *entry; ) {
            int entryLen = wcslen(entry);
            if (const wchar_t *equal = wcschr(entry, L'=')) {
                int nameLen = equal - entry;
                QString name = QString::fromWCharArray(entry, nameLen);
                QString value = QString::fromWCharArray(equal + 1, entryLen - nameLen - 1);
                env.d->hash.insert(QProcessEnvironmentPrivate::Key(name), value);
            }
            entry += entryLen + 1;
        }
        FreeEnvironmentStringsW(envStrings);
    }
#endif
    return env;
}
Esempio n. 17
0
LPVOID __cdecl __crtGetEnvironmentStringsW(
        VOID
        )
{
    void *penv;
    wchar_t *pwch;
    wchar_t *wbuffer;
    int total_size;

    if ( NULL == (penv = GetEnvironmentStringsW()) )
        return NULL;

    /* find out how big a buffer is needed */

    pwch = penv;
    while ( *pwch != L'\0' ) {
        if ( *++pwch == L'\0' )
            pwch++;
    }

    total_size = (int)((char *)pwch - (char *)penv) +
                 (int)sizeof( wchar_t );

    /* allocate the buffer */

    if ( NULL == (wbuffer = _malloc_crt( total_size )) ) {
        FreeEnvironmentStringsW( penv );
        return NULL;
    }

    /* copy environment strings to buffer */

    memcpy( wbuffer, penv, total_size );

    FreeEnvironmentStringsW( penv );

    return (LPVOID)wbuffer;
}
Esempio n. 18
0
LPVOID __cdecl __crtGetEnvironmentStringsA(
	VOID
	)
{
        static int f_use = 0;
	wchar_t *wEnv;
	wchar_t *wTmp;
	char *aEnv;
	char *aTmp;
	int nSizeW;
	int nSizeA;

        /* 
         * Look for 'preferred' flavor. Otherwise use available flavor.
         * Must actually call the function to ensure it's not a stub.
         */

        if ( 0 == f_use )
        {
            if ( NULL != (wEnv = GetEnvironmentStringsW()) )
                f_use = USE_W;

            else if ( NULL != (aEnv = GetEnvironmentStringsA()) )
                f_use = USE_A;

            else
                return NULL;
        }

        /* Use "W" version */

        if (USE_W == f_use)
        {
            /* obtain wide environment block */
	    if ( NULL == wEnv )
		if ( NULL == (wEnv = GetEnvironmentStringsW()) )
		    return NULL;

            /* look for double null that indicates end of block */
            wTmp = wEnv;
	    while ( *wTmp != L'\0' ) {
                if ( *++wTmp == L'\0' )
                    wTmp++;
            }

            /* calculate total size of block, including all nulls */
            nSizeW = wTmp - wEnv + 1;

            /* find out how much space needed for multi-byte environment */
            nSizeA = WideCharToMultiByte(   CP_ACP,
                                            0,
                                            wEnv,
                                            nSizeW,
                                            NULL,
                                            0,
                                            NULL,
                                            NULL );

            /* allocate space for multi-byte string */
            if ( (nSizeA == 0) || 
		 ((aEnv = (char *)_malloc_crt(nSizeA)) == NULL) )
	    {
		FreeEnvironmentStringsW( wEnv );
                return NULL;
	    }

            /* do the conversion */
            if ( !WideCharToMultiByte(  CP_ACP,
                                        0,
                                        wEnv,
                                        nSizeW,
                                        aEnv,
                                        nSizeA,
                                        NULL,
                                        NULL ) )
	    {
		_free_crt( aEnv );
                aEnv = NULL; 
	    }

            FreeEnvironmentStringsW( wEnv );
            return aEnv;
        }

        /* Use "A" version */

        if ( USE_A == f_use )
        {
	    if ( NULL == aEnv )
		if ( NULL == (aEnv = GetEnvironmentStringsA()) )
		    return NULL;

	    /* determine how big a buffer is needed */

	    aTmp = aEnv;

	    while ( *aTmp != '\0' ) {
		if ( *++aTmp == '\0' )
		    aTmp++;
	    }
	
	    nSizeA = aTmp - aEnv + 1;

	    if ( NULL == (aTmp = _malloc_crt( nSizeA )) ) {
		FreeEnvironmentStringsA( aEnv );
		return NULL;
	    }

	    memcpy( aTmp, aEnv, nSizeA );

	    FreeEnvironmentStringsA( aEnv );

	    return aTmp;
        }

        return NULL;
}
Esempio n. 19
0
void init_getenv_state(GETENV_STATE *state)
{
    erts_rwmtx_rlock(&environ_rwmtx);
    state->environment_strings = GetEnvironmentStringsW();
    state->next_string = state->environment_strings;
}
Esempio n. 20
0
BOOLEAN DosBIOSInitialize(VOID)
{
    PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);

    LPWSTR SourcePtr, Environment;
    LPSTR AsciiString;
    DWORD AsciiSize;
    LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);

#if 0
    UCHAR i;
    CHAR CurrentDirectory[MAX_PATH];
    CHAR DosDirectory[DOS_DIR_LENGTH];
    LPSTR Path;

    FILE *Stream;
    WCHAR Buffer[256];
#endif

    /* Initialize the MCB */
    Mcb->BlockType = 'Z';
    Mcb->Size = USER_MEMORY_SIZE;
    Mcb->OwnerPsp = 0;

    /* Initialize the link MCB to the UMB area */
    Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT + USER_MEMORY_SIZE + 1);
    Mcb->BlockType = 'M';
    Mcb->Size = UMB_START_SEGMENT - FIRST_MCB_SEGMENT - USER_MEMORY_SIZE - 2;
    Mcb->OwnerPsp = SYSTEM_PSP;

    /* Initialize the UMB area */
    Mcb = SEGMENT_TO_MCB(UMB_START_SEGMENT);
    Mcb->BlockType = 'Z';
    Mcb->Size = UMB_END_SEGMENT - UMB_START_SEGMENT;
    Mcb->OwnerPsp = 0;

    /* Get the environment strings */
    SourcePtr = Environment = GetEnvironmentStringsW();
    if (Environment == NULL) return FALSE;

    /* Fill the DOS system environment block */
    while (*SourcePtr)
    {
        /* Get the size of the ASCII string */
        AsciiSize = WideCharToMultiByte(CP_ACP,
                                        0,
                                        SourcePtr,
                                        -1,
                                        NULL,
                                        0,
                                        NULL,
                                        NULL);

        /* Allocate memory for the ASCII string */
        AsciiString = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, AsciiSize);
        if (AsciiString == NULL)
        {
            FreeEnvironmentStringsW(Environment);
            return FALSE;
        }

        /* Convert to ASCII */
        WideCharToMultiByte(CP_ACP,
                            0,
                            SourcePtr,
                            -1,
                            AsciiString,
                            AsciiSize,
                            NULL,
                            NULL);

        /* Copy the string into DOS memory */
        strcpy(DestPtr, AsciiString);

        /* Move to the next string */
        SourcePtr += wcslen(SourcePtr) + 1;
        DestPtr += strlen(AsciiString);
        *(DestPtr++) = 0;

        /* Free the memory */
        HeapFree(GetProcessHeap(), 0, AsciiString);
    }
    *DestPtr = 0;

    /* Free the memory allocated for environment strings */
    FreeEnvironmentStringsW(Environment);


#if 0

    /* Clear the current directory buffer */
    ZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));

    /* Get the current directory */
    if (!GetCurrentDirectoryA(MAX_PATH, CurrentDirectory))
    {
        // TODO: Use some kind of default path?
        return FALSE;
    }

    /* Convert that to a DOS path */
    if (!GetShortPathNameA(CurrentDirectory, DosDirectory, DOS_DIR_LENGTH))
    {
        // TODO: Use some kind of default path?
        return FALSE;
    }

    /* Set the drive */
    CurrentDrive = DosDirectory[0] - 'A';

    /* Get the directory part of the path */
    Path = strchr(DosDirectory, '\\');
    if (Path != NULL)
    {
        /* Skip the backslash */
        Path++;
    }

    /* Set the directory */
    if (Path != NULL)
    {
        strncpy(CurrentDirectories[CurrentDrive], Path, DOS_DIR_LENGTH);
    }

    /* Read CONFIG.SYS */
    Stream = _wfopen(DOS_CONFIG_PATH, L"r");
    if (Stream != NULL)
    {
        while (fgetws(Buffer, sizeof(Buffer)/sizeof(Buffer[0]), Stream))
        {
            // TODO: Parse the line
        }
        fclose(Stream);
    }

#endif


    /* Register the DOS 32-bit Interrupts */
    // RegisterDosInt32(0x20, DosInt20h);

    /* Initialize the DOS kernel */
    return DosKRNLInitialize();
}
Esempio n. 21
0
int main() {

	int argc;
	wchar_t ** argv = CommandLineToArgvW(GetCommandLine(), &argc);

	// Make sure that we've been passed the right number of arguments
	if (argc < 8) {
		_tprintf(_T("Usage: %s (four inheritable event handles) (CommandLineToSpawn)\n"),
				argv[0]);
		return(0);
	}

	// Construct the full command line
	int nCmdLineLength= MAX_CMD_LINE_LENGTH;
	wchar_t * szCmdLine= (wchar_t *)malloc(nCmdLineLength * sizeof(wchar_t));
	szCmdLine[0]= 0;
	int nPos = 0;

	for(int i = 8; i < argc; ++i)
	{
		int nCpyLen;
		int len= wcslen(argv[i]);
		int requiredSize= nPos+len+2;
		if (requiredSize > 32*1024) {
#ifdef DEBUG_MONITOR
			OutputDebugStringW(_T("Command line too long!\n"));
#endif
			return 0;
		}
		ensureSize(&szCmdLine, &nCmdLineLength, requiredSize);
		if (NULL == szCmdLine) {
#ifdef DEBUG_MONITOR
			OutputDebugStringW(_T("Not enough memory to build cmd line!\n"));
#endif
			return 0;
		}
		if(0 > (nCpyLen = copyTo(szCmdLine + nPos, argv[i], len, nCmdLineLength - nPos)))
		{
#ifdef DEBUG_MONITOR
			OutputDebugStringW(_T("Not enough space to build command line\n"));
#endif
			return 0;
		}
		nPos += nCpyLen;
		szCmdLine[nPos] = _T(' ');
		++nPos;
	}
	szCmdLine[nPos] = _T('\0');

	STARTUPINFOW si = {sizeof(si)};
	PROCESS_INFORMATION pi = {0};
	DWORD dwExitCode = 0;
#ifdef DEBUG_MONITOR
	int currentPID = GetCurrentProcessId();
	wchar_t buffer[MAX_CMD_LINE_LENGTH];
#endif

	BOOL exitProc = FALSE;
	HANDLE waitEvent = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[4]);
	HANDLE h[5];
	h[0] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[3]);	// simulated SIGINT (CTRL-C or Cygwin 'kill -SIGINT')
//  h[1] we reserve for the process handle
	h[2] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[5]); // simulated SIGTERM
	h[3] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[6]); // simulated SIGKILL
	h[4] = OpenEventW(EVENT_ALL_ACCESS, TRUE, argv[7]); // CTRL-C, in all cases
	
	SetConsoleCtrlHandler(HandlerRoutine, TRUE);

	int parentPid = wcstol(argv[1], NULL, 10);
	int nCounter = wcstol(argv[2], NULL, 10);
	wchar_t inPipeName[PIPE_NAME_LENGTH];
	wchar_t outPipeName[PIPE_NAME_LENGTH];
	wchar_t errPipeName[PIPE_NAME_LENGTH];

	swprintf(inPipeName, L"\\\\.\\pipe\\stdin%08i%010i", parentPid, nCounter);
	swprintf(outPipeName, L"\\\\.\\pipe\\stdout%08i%010i", parentPid, nCounter);
	swprintf(errPipeName, L"\\\\.\\pipe\\stderr%08i%010i", parentPid, nCounter);
#ifdef DEBUG_MONITOR
	swprintf(buffer, _T("Pipes: %s, %s, %s\n"), inPipeName, outPipeName, errPipeName);
	OutputDebugStringW(buffer);
#endif

	HANDLE stdHandles[3];

	SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.bInheritHandle = TRUE;
	sa.lpSecurityDescriptor = NULL;

	if((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateFileW(inPipeName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, &sa))) ||
			(INVALID_HANDLE_VALUE == (stdHandles[1] = CreateFileW(outPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa))) ||
			(INVALID_HANDLE_VALUE == (stdHandles[2] = CreateFileW(errPipeName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, &sa))))
	{
#ifdef DEBUG_MONITOR
		swprintf(buffer, _T("Failed to open pipe %i, %i, %i: %i\n"), stdHandles[0], stdHandles[1], stdHandles[2], GetLastError());
		OutputDebugStringW(buffer);
#endif
		CloseHandle(stdHandles[0]);
		CloseHandle(stdHandles[1]);
		CloseHandle(stdHandles[2]);
		return -1;;
	}
	SetHandleInformation(stdHandles[0], HANDLE_FLAG_INHERIT, TRUE);
	SetHandleInformation(stdHandles[1], HANDLE_FLAG_INHERIT, TRUE);
	SetHandleInformation(stdHandles[2], HANDLE_FLAG_INHERIT, TRUE);

	if(!SetStdHandle(STD_INPUT_HANDLE, stdHandles[0]) ||
			!SetStdHandle(STD_OUTPUT_HANDLE, stdHandles[1]) ||
			!SetStdHandle(STD_ERROR_HANDLE, stdHandles[2])) {
#ifdef DEBUG_MONITOR
		swprintf(buffer, _T("Failed to reassign standard streams: %i\n"), GetLastError());
		OutputDebugStringW(buffer);
#endif
		CloseHandle(stdHandles[0]);
		CloseHandle(stdHandles[1]);
		CloseHandle(stdHandles[2]);
		return -1;;
	}

#ifdef DEBUG_MONITOR
	wchar_t * lpvEnv = GetEnvironmentStringsW();

	// If the returned pointer is NULL, exit.
	if (lpvEnv == NULL)
	OutputDebugStringW(_T("Cannot Read Environment\n"));
	else {
		// Variable strings are separated by NULL byte, and the block is 
		// terminated by a NULL byte. 

		OutputDebugStringW(_T("Starter: Environment\n"));
		for (wchar_t * lpszVariable = (wchar_t *) lpvEnv; *lpszVariable; lpszVariable+=wcslen(lpszVariable) + 1) {
			swprintf(buffer, _T("%s\n"), lpszVariable);
			OutputDebugStringW(buffer);
		}

		FreeEnvironmentStringsW(lpvEnv);
	}
#endif
#ifdef DEBUG_MONITOR
	swprintf(buffer, _T("Starting: %s\n"), szCmdLine);
	OutputDebugStringW(buffer);
#endif
	// Create job object
	HANDLE hJob = CreateJobObject(NULL, NULL);
	
	// Spawn the other processes as part of this Process Group
	BOOL f = CreateProcessW(NULL, szCmdLine, NULL, NULL, TRUE,
			0, NULL, NULL, &si, &pi);

	// We don't need them any more
	CloseHandle(stdHandles[0]);
	CloseHandle(stdHandles[1]);
	CloseHandle(stdHandles[2]);
	
	if (f) {
#ifdef DEBUG_MONITOR
		swprintf(buffer, _T("Process %i started\n"), pi.dwProcessId);
		OutputDebugStringW(buffer);
#endif
		SetEvent(waitEvent); // Means thar process has been spawned
		CloseHandle(pi.hThread);
		h[1] = pi.hProcess;

		if(NULL != hJob) {
			if(!AssignProcessToJobObject(hJob, pi.hProcess)) {
#ifdef DEBUG_MONITOR
				swprintf(buffer, _T("Cannot assign process %i to a job\n"), pi.dwProcessId);
				OutputDebugStringW(buffer);
				DisplayErrorMessage();
#endif
			}
		}

		while(!exitProc)
		{
			// Wait for the spawned-process to die or for the event
			// indicating that the processes should be forcibly killed.
			DWORD event = WaitForMultipleObjects(5, h, FALSE, INFINITE);
			switch (event)
			{
			case WAIT_OBJECT_0 + 0: // SIGINT
			case WAIT_OBJECT_0 + 4: // CTRL-C
#ifdef DEBUG_MONITOR
				swprintf(buffer, _T("starter (PID %i) received CTRL-C event\n"), currentPID);
				OutputDebugStringW(buffer);
#endif
				if ((event == (WAIT_OBJECT_0 + 0)) && isCygwin(h[1])) {
					// Need to issue a kill command
					wchar_t kill[1024];
					swprintf(kill, L"kill -SIGINT %d", pi.dwProcessId);
					if (!runCygwinCommand(kill)) {
						// fall back to console event
						GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
					}
				} else {
					GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
				}

				SetEvent(waitEvent);
				break;

			case WAIT_OBJECT_0 + 1: // App terminated normally
				// Make it's exit code our exit code
#ifdef DEBUG_MONITOR
				swprintf(buffer, _T("starter: launched process has been terminated(PID %i)\n"),
						pi.dwProcessId);
				OutputDebugStringW(buffer);
#endif
				GetExitCodeProcess(pi.hProcess, &dwExitCode);
				exitProc = TRUE;
				break;

			// Terminate and Kill behavior differ only for cygwin processes, where
			// we use the cygwin 'kill' command. We send a SIGKILL in one case,
			// SIGTERM in the other. For non-cygwin processes, both requests
			// are treated exactly the same
			case WAIT_OBJECT_0 + 2:	// TERM
			case WAIT_OBJECT_0 + 3:	// KILL
			{
				const wchar_t* signal = (event == WAIT_OBJECT_0 + 2) ? L"TERM" : L"KILL";
#ifdef DEBUG_MONITOR
				swprintf(buffer, _T("starter received %s event (PID %i)\n"), signal, currentPID);
				OutputDebugStringW(buffer);
#endif
				if (isCygwin(h[1])) {
					// Need to issue a kill command
					wchar_t kill[1024];
					swprintf(kill, L"kill -%s %d", signal, pi.dwProcessId);
					if (!runCygwinCommand(kill)) {
						// fall back to console event
						GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
					}
				} else {				
					GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
				}
				
				SetEvent(waitEvent);
				
				if(NULL != hJob) {
					if(!TerminateJobObject(hJob, (DWORD)-1)) {
#ifdef DEBUG_MONITOR
						OutputDebugStringW(_T("Cannot terminate job\n"));
						DisplayErrorMessage();
#endif
					}
				}

				// Note that we keep trucking until the child process terminates (case WAIT_OBJECT_0 + 1)
				break;
			}

			default:
				// Unexpected code
#ifdef DEBUG_MONITOR
				DisplayErrorMessage();
#endif
				exitProc = TRUE;
				break;
			}

		}
	} else {
#ifdef DEBUG_MONITOR
		swprintf(buffer, _T("Cannot start: %s\n"), szCmdLine);
		OutputDebugStringW(buffer);

		DisplayErrorMessage();
#endif
	}

	if (NULL != szCmdLine)
	{
		free(szCmdLine);
	}

	CloseHandle(waitEvent);
	CloseHandle(h[0]);
	CloseHandle(h[1]);
	CloseHandle(h[2]);
	CloseHandle(h[3]);
	CloseHandle(h[4]);

	return(dwExitCode);
}
/**
 * Launch a child process without elevated privilege.
 */
static BOOL
LaunchAsNormalUser(const PRUnichar *exePath, PRUnichar *cl)
{
#ifdef WINCE
  return PR_FALSE;
#else
  if (!pCreateProcessWithTokenW) {
    // IsUserAnAdmin is not present on Win9x and not exported by name on Win2k
    *(FARPROC *)&pIsUserAnAdmin =
        GetProcAddress(GetModuleHandleA("shell32.dll"), "IsUserAnAdmin");

    // CreateProcessWithTokenW is not present on WinXP or earlier
    *(FARPROC *)&pCreateProcessWithTokenW =
        GetProcAddress(GetModuleHandleA("advapi32.dll"),
                       "CreateProcessWithTokenW");

    if (!pCreateProcessWithTokenW)
      return FALSE;
  }

  // do nothing here if we are not elevated or IsUserAnAdmin is not present.
  if (!pIsUserAnAdmin || pIsUserAnAdmin && !pIsUserAnAdmin())
    return FALSE;

  // borrow the shell token to drop the privilege
  HWND hwndShell = FindWindowA("Progman", NULL);
  DWORD dwProcessId;
  GetWindowThreadProcessId(hwndShell, &dwProcessId);

  HANDLE hProcessShell = OpenProcess(MAXIMUM_ALLOWED, FALSE, dwProcessId);
  if (!hProcessShell)
    return FALSE;

  HANDLE hTokenShell;
  BOOL ok = OpenProcessToken(hProcessShell, MAXIMUM_ALLOWED, &hTokenShell);
  CloseHandle(hProcessShell);
  if (!ok)
    return FALSE;

  HANDLE hNewToken;
  ok = DuplicateTokenEx(hTokenShell,
                        MAXIMUM_ALLOWED,
                        NULL,
                        SecurityDelegation,
                        TokenPrimary,
                        &hNewToken);
  CloseHandle(hTokenShell);
  if (!ok)
    return FALSE;

  STARTUPINFOW si = {sizeof(si), 0};
  PROCESS_INFORMATION pi = {0};

  // When launching with reduced privileges, environment inheritance
  // (passing NULL as lpEnvironment) doesn't work correctly. Pass our
  // current environment block explicitly
  WCHAR* myenv = GetEnvironmentStringsW();

  ok = pCreateProcessWithTokenW(hNewToken,
                                0,    // profile is already loaded
                                exePath,
                                cl,
                                CREATE_UNICODE_ENVIRONMENT,
                                myenv, // inherit my environment
                                NULL, // use my current directory
                                &si,
                                &pi);

  if (myenv)
    FreeEnvironmentStringsW(myenv);

  CloseHandle(hNewToken);
  if (!ok)
    return FALSE;

  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);

  return TRUE;
#endif
}
Esempio n. 23
0
DWORD main(int argc, char **argv)
{
    HANDLE hCompletionPort;
    BOOL fNeedHelp = FALSE;
    WCHAR wzzDrop[1024] = L"build\0nmake\0";

    GetSystemTimeAsFileTime((FILETIME *)&s_llStartTime);
    StringCchPrintfA(s_szPipe, ARRAYSIZE(s_szPipe), "%s.%d", TBLOG_PIPE_NAME, GetCurrentProcessId());

    int arg = 1;
    for (; arg < argc && (argv[arg][0] == '-' || argv[arg][0] == '/'); arg++) {
        CHAR *argn = argv[arg] + 1;
        CHAR *argp = argn;
        while (*argp && *argp != ':' && *argp != '=') {
            argp++;
        }
        if (*argp == ':' || *argp == '=') {
            *argp++ = '\0';
        }

        switch (argn[0]) {

          case 'd':                                     // Drop Processes
          case 'D':
            if (*argp) {
                PWCHAR pwz = wzzDrop;
                while (*argp) {
                    if (*argp == ';') {
                        *pwz++ = '\0';
                    }
                    else {
                        *pwz++ = *argp++;
                    }
                }
                *pwz++ = '\0';
                *pwz = '\0';
            }
          case 'o':                                 // Output file.
          case 'O':
            StringCchCopyA(s_szLogFile, ARRAYSIZE(s_szLogFile), argp);
            break;

          case 'v':                                     // Verbose
          case 'V':
            s_fVerbose = TRUE;
            break;

          case '?':                                 // Help.
            fNeedHelp = TRUE;
            break;

          default:
            fNeedHelp = TRUE;
            printf("TRACEBLD: Bad argument: %s:%s\n", argn, argp);
            break;
        }
    }

    if (arg >= argc) {
        fNeedHelp = TRUE;
    }

    if (fNeedHelp) {
        printf("Usage:\n"
               "    tracebld [options] command {command arguments}\n"
               "Options:\n"
               "    /o:file    Log all events to the output files.\n"
               "    /?         Display this help message.\n"
               "Summary:\n"
               "    Runs the build commands and figures out which files have dependencies..\n"
               "\n");
        exit(9001);
    }

    // Create the completion port.
    hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
    if (hCompletionPort == NULL) {
        MyErrExit("CreateIoCompletionPort");
    }

    // Create completion port worker threads.
    //
    CreateWorkers(hCompletionPort);
    CreatePipeConnection(hCompletionPort, 0);

    printf("TRACEBLD: Ready for clients.  Press Ctrl-C to stop.\n");

    /////////////////////////////////////////////////////////// Validate DLLs.
    //
    CHAR szTmpPath[MAX_PATH];
    CHAR szExePath[MAX_PATH];
    CHAR szDllPath[MAX_PATH];
    PCHAR pszFilePart = NULL;

    if (!GetModuleFileNameA(NULL, szTmpPath, ARRAYSIZE(szTmpPath))) {
        printf("TRACEBLD: Couldn't retreive exe name.\n");
        return 9002;
    }
    if (!GetFullPathNameA(szTmpPath, ARRAYSIZE(szExePath), szExePath, &pszFilePart) ||
        pszFilePart == NULL) {
        printf("TRACEBLD: Error: %s is not a valid path name..\n", szTmpPath);
        return 9002;
    }

    StringCchCopyA(pszFilePart, szExePath + ARRAYSIZE(szExePath) - pszFilePart,
             "trcbld" DETOURS_STRINGIFY(DETOURS_BITS) ".dll");
    StringCchCopyA(szDllPath, ARRAYSIZE(szDllPath), szExePath);

    //////////////////////////////////////////////////////////////////////////
    STARTUPINFOA si;
    PROCESS_INFORMATION pi;
    CHAR szCommand[2048];
    CHAR szExe[MAX_PATH];
    CHAR szFullExe[MAX_PATH] = "\0";
    PCHAR pszFileExe = NULL;

    ZeroMemory(&si, sizeof(si));
    ZeroMemory(&pi, sizeof(pi));
    si.cb = sizeof(si);

    szCommand[0] = L'\0';

    StringCchCopyA(szExe, sizeof(szExe), argv[arg]);
    for (; arg < argc; arg++) {
        if (strchr(argv[arg], ' ') != NULL || strchr(argv[arg], '\t') != NULL) {
            StringCchCatA(szCommand, sizeof(szCommand), "\"");
            StringCchCatA(szCommand, sizeof(szCommand), argv[arg]);
            StringCchCatA(szCommand, sizeof(szCommand), "\"");
        }
        else {
            StringCchCatA(szCommand, sizeof(szCommand), argv[arg]);
        }

        if (arg + 1 < argc) {
            StringCchCatA(szCommand, sizeof(szCommand), " ");
        }
    }
    printf("TRACEBLD: Starting: `%s'\n", szCommand);
    printf("TRACEBLD:   with `%s'\n", szDllPath);
    fflush(stdout);

    DWORD dwFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED;

    SetLastError(0);
    SearchPathA(NULL, szExe, ".exe", ARRAYSIZE(szFullExe), szFullExe, &pszFileExe);


    if (!DetourCreateProcessWithDllExA(szFullExe[0] ? szFullExe : NULL, szCommand,
                                       NULL, NULL, TRUE, dwFlags, NULL, NULL,
                                       &si, &pi, szDllPath, NULL)) {
        printf("TRACEBLD: DetourCreateProcessWithDllEx failed: %d\n", GetLastError());
        ExitProcess(9007);
    }

    ZeroMemory(&s_Payload, sizeof(s_Payload));
    s_Payload.nParentProcessId = GetCurrentProcessId();
    s_Payload.nTraceProcessId = GetCurrentProcessId();
    s_Payload.nGeneology = 1;
    s_Payload.rGeneology[0] = 0;
    StringCchCopyW(s_Payload.wzStdin, ARRAYSIZE(s_Payload.wzStdin), L"\\\\.\\CONIN$");
    StringCchCopyW(s_Payload.wzStdout, ARRAYSIZE(s_Payload.wzStdout), L"\\\\.\\CONOUT$");
    StringCchCopyW(s_Payload.wzStderr, ARRAYSIZE(s_Payload.wzStderr), L"\\\\.\\CONOUT$");
    StringCchCopyW(s_Payload.wzParents, ARRAYSIZE(s_Payload.wzParents), L"");
    CopyEnvironment(s_Payload.wzzDrop, wzzDrop);
    LPWCH pwStrings = GetEnvironmentStringsW();
    CopyEnvironment(s_Payload.wzzEnvironment, pwStrings);
    FreeEnvironmentStringsW(pwStrings);

    if (!DetourCopyPayloadToProcess(pi.hProcess, s_guidTrace,
                                    &s_Payload, sizeof(s_Payload))) {
        printf("TRACEBLD: DetourCopyPayloadToProcess failed: %d\n", GetLastError());
        ExitProcess(9008);
    }

    ResumeThread(pi.hThread);

    WaitForSingleObject(pi.hProcess, INFINITE);

    DWORD dwResult = 0;
    if (!GetExitCodeProcess(pi.hProcess, &dwResult)) {
        printf("TRACEBLD: GetExitCodeProcess failed: %d\n", GetLastError());
        return 9008;
    }

    printf("TRACEBLD: %d processes.\n", s_nTotalClients);

    return dwResult;
}
Esempio n. 24
0
APR_DECLARE(apr_status_t) apr_app_initialize(int *argc,
                                             const char * const * *argv,
                                             const char * const * *env)
{
    apr_status_t rv = apr_initialize();

    if (rv != APR_SUCCESS) {
        return rv;
    }

#if defined(_WIN32_WCE)
    apr_app_init_complete = 1;
#elif APR_HAS_UNICODE_FS
    IF_WIN_OS_IS_UNICODE
    {
        apr_wchar_t **wstrs;
        apr_wchar_t *sysstr;
        int wstrc;
        int dupenv;

        if (apr_app_init_complete) {
            return rv;
        }

        apr_app_init_complete = 1;

        sysstr = GetCommandLineW();
        if (sysstr) {
            wstrs = CommandLineToArgvW(sysstr, &wstrc);
            if (wstrs) {
                *argc = apr_wastrtoastr(argv, wstrs, wstrc);
                GlobalFree(wstrs);
            }
        }

        sysstr = GetEnvironmentStringsW();
        dupenv = warrsztoastr(&_environ, sysstr, -1);

        if (env) {
            *env = apr_malloc_dbg((dupenv + 1) * sizeof (char *),
                                  __FILE__, __LINE__ );
            memcpy((void*)*env, _environ, (dupenv + 1) * sizeof (char *));
        }
        else {
        }

        FreeEnvironmentStringsW(sysstr);

        /* MSVCRT will attempt to maintain the wide environment calls
         * on _putenv(), which is bogus if we've passed a non-ascii
         * string to _putenv(), since they use MultiByteToWideChar
         * and breaking the implicit utf-8 assumption we've built.
         *
         * Reset _wenviron for good measure.
         */
        if (_wenviron) {
            apr_wchar_t **wenv = _wenviron;
            _wenviron = NULL;
            free(wenv);
        }

    }
#endif
    return rv;
}
Esempio n. 25
0
ProgramRunner::ProgramRunner(const BSONObj& args, const BSONObj& env) {
    uassert(ErrorCodes::FailedToParse,
            "cannot pass an empty argument to ProgramRunner",
            !args.isEmpty());

    string program(args.firstElement().valuestrsafe());
    uassert(ErrorCodes::FailedToParse,
            "invalid program name passed to ProgramRunner",
            !program.empty());
    boost::filesystem::path programPath = findProgram(program);
    boost::filesystem::path programName = programPath.stem();

    string prefix("mongod-");
    bool isMongodProgram = string("mongod") == programName ||
        programName.string().compare(0, prefix.size(), prefix) == 0;
    prefix = "mongos-";
    bool isMongosProgram = string("mongos") == programName ||
        programName.string().compare(0, prefix.size(), prefix) == 0;

    if (isMongodProgram) {
        _name = "d";
    } else if (isMongosProgram) {
        _name = "s";
    } else if (programName == "mongobridge") {
        _name = "b";
    } else {
        _name = "sh";
    }

    _argv.push_back(programPath.string());

    _port = -1;

    // Parse individual arguments into _argv
    BSONObjIterator j(args);
    j.next();  // skip program name (handled above)
    while (j.more()) {
        BSONElement e = j.next();
        string str;
        if (e.isNumber()) {
            stringstream ss;
            ss << e.number();
            str = ss.str();
        } else {
            verify(e.type() == mongo::String);
            str = e.valuestr();
        }
        if (str == "--port") {
            _port = -2;
        } else if (_port == -2) {
            _port = strtol(str.c_str(), 0, 10);
        } else if (isMongodProgram && str == "--configsvr") {
            _name = "c";
        }
        _argv.push_back(str);
    }

    // Load explicitly set environment key value pairs into _envp.
    for (const BSONElement& e : env) {
        // Environment variable values must be strings
        verify(e.type() == mongo::String);

        _envp.emplace(std::string(e.fieldName()), std::string(e.valuestr()));
    }

// Import this process' environment into _envp, for all keys that have not already been set.
// We need to do this so that the child process has all the PATH and locale variables, unless
// we explicitly override them.
#ifdef _WIN32
    wchar_t* processEnv = GetEnvironmentStringsW();
    ON_BLOCK_EXIT(
        [](wchar_t* toFree) {
            if (toFree)
                FreeEnvironmentStringsW(toFree);
        },
        processEnv);

    // Windows' GetEnvironmentStringsW returns a NULL terminated array of NULL separated
    // <key>=<value> pairs.
    while (processEnv && *processEnv) {
        std::wstring envKeyValue(processEnv);
        size_t splitPoint = envKeyValue.find('=');
        invariant(splitPoint != std::wstring::npos);
        std::string envKey = toUtf8String(envKeyValue.substr(0, splitPoint));
        std::string envValue = toUtf8String(envKeyValue.substr(splitPoint + 1));
        _envp.emplace(std::move(envKey), std::move(envValue));
        processEnv += envKeyValue.size() + 1;
    }
#else
    // environ is a POSIX defined array of char*s. Each char* in the array is a <key>=<value>\0
    // pair.
    char** environEntry = environ;
    while (*environEntry) {
        std::string envKeyValue(*environEntry);
        size_t splitPoint = envKeyValue.find('=');
        invariant(splitPoint != std::string::npos);
        std::string envKey = envKeyValue.substr(0, splitPoint);
        std::string envValue = envKeyValue.substr(splitPoint + 1);
        _envp.emplace(std::move(envKey), std::move(envValue));
        ++environEntry;
    }
#endif
    bool needsPort = isMongodProgram || isMongosProgram || (programName == "mongobridge");
    if (!needsPort) {
        _port = -1;
    }
    uassert(ErrorCodes::FailedToParse,
            str::stream() << "a port number is expected when running " << program
                          << " from the shell",
            !needsPort || _port >= 0);

    uassert(ErrorCodes::BadValue,
            str::stream() << "can't start " << program << ", port " << _port << " already in use",
            _port < 0 || !registry.isPortRegistered(_port));
}
LPVOID __cdecl __crtGetEnvironmentStringsW(
        VOID
        )
{
        static int f_use = 0;
        void *penv = NULL;
        char *pch;
        wchar_t *pwch;
        wchar_t *wbuffer;
        int total_size = 0;
        int str_size;

        /*
         * Look for unstubbed 'preferred' flavor. Otherwise use available flavor.
         * Must actually call the function to ensure it's not a stub.
         */

        if ( 0 == f_use )
        {
            if ( NULL != (penv = GetEnvironmentStringsW()) )
                f_use = USE_W;

            else if ( NULL != (penv = GetEnvironmentStringsA()) )
                f_use = USE_A;
            else
                return NULL;
        }

        /* Use "W" version */

        if ( USE_W == f_use )
        {
            if ( NULL == penv )
                if ( NULL == (penv = GetEnvironmentStringsW()) )
                    return NULL;

            /* find out how big a buffer is needed */

            pwch = penv;
            while ( *pwch != L'\0' ) {
                if ( *++pwch == L'\0' )
                    pwch++;
            }

            total_size = (char *)pwch - (char *)penv + sizeof( wchar_t );

            /* allocate the buffer */

            if ( NULL == (wbuffer = _malloc_crt( total_size )) ) {
                FreeEnvironmentStringsW( penv );
                return NULL;
            }

            /* copy environment strings to buffer */

            memcpy( wbuffer, penv, total_size );

            FreeEnvironmentStringsW( penv );

            return (LPVOID)wbuffer;
        }

        /* Use "A" version */

        if ( USE_A == f_use )
        {
            /*
             * Convert strings and return the requested information.
             */
            if ( NULL == penv )
                if ( NULL == (penv = GetEnvironmentStringsA()) )
                    return NULL;

            pch = penv;

            /* find out how big a buffer we need */
            while ( *pch != '\0' )
            {
                if ( 0 == (str_size =
                      MultiByteToWideChar( __lc_codepage,
                                           MB_PRECOMPOSED,
                                           pch,
                                           -1,
                                           NULL,
                                           0 )) )
                    return 0;

                total_size += str_size;
                pch += strlen(pch) + 1;
            }

            /* room for final NULL */
            total_size++;

            /* allocate enough space for chars */
            if ( NULL == (wbuffer = (wchar_t *)
                 _malloc_crt( total_size * sizeof( wchar_t ) )) )
            {
                FreeEnvironmentStringsA( penv );
                return NULL;
            }

            /* do the conversion */
            pch = penv;
            pwch = wbuffer;
            while (*pch != '\0')
            {
                if ( 0 == MultiByteToWideChar( __lc_codepage,
                                               MB_PRECOMPOSED,
                                               pch,
                                               -1,
                                               pwch,
                                               total_size - (pwch -
                                                 wbuffer) ) )
                {
                    _free_crt( wbuffer );
                    FreeEnvironmentStringsA( penv );
                    return NULL;
                }

                pch += strlen(pch) + 1;
                pwch += wcslen(pwch) + 1;
            }
            *pwch = L'\0';

            FreeEnvironmentStringsA( penv );

            return (LPVOID)wbuffer;

        }
        else   /* f_use is neither USE_A nor USE_W */
            return NULL;
}
Esempio n. 27
0
/*
 * routine in DLL to do initialization (in this case, C++ constructors)
 */
extern void __cdecl _initterm(_PVFV *, _PVFV *);

#ifdef _WINMAIN_

#ifdef WPRFLAG
int wWinMainCRTStartup(
#else  /* WPRFLAG */
int WinMainCRTStartup(
#endif  /* WPRFLAG */

#else  /* _WINMAIN_ */

#ifdef WPRFLAG
int wmainCRTStartup(
#else  /* WPRFLAG */
int mainCRTStartup(
#endif  /* WPRFLAG */

#endif  /* _WINMAIN_ */
        void
        )
{
        int argc = 0;   /* three standard arguments to main */
        _TSCHAR **argv = NULL;
        _TSCHAR **envp = NULL;

        int argret = 0;

#ifdef _WINMAIN_
        _TUCHAR *lpszCommandLine;
        STARTUPINFO StartupInfo;
#endif  /* _WINMAIN_ */

#ifdef WPRFLAG
	int envp_count = 0;
#endif

        //_startupinfo    startinfo;

        /*
         * Determine if this is a managed application
         */
        //managedapp = check_managed_app();

	/*
	 * Set __app_type properly
	 */
#ifdef _WINMAIN_
	//__set_app_type(_GUI_APP);
#else  /* _WINMAIN_ */
	//__set_app_type(_CONSOLE_APP);
#endif  /* _WINMAIN_ */

#ifdef _WINMAIN_
#ifdef WPRFLAG
	dbgmsg("wWinMainCRTStartup()");
#else
	dbgmsg("WinMainCRTStartup()");
#endif
#else
#ifdef WPRFLAG
	dbgmsg("wmainCRTStartup()");
#else
	dbgmsg("mainCRTStartup()");
#endif
#endif
	/*
	 * Mark this module as an EXE file so that atexit/_onexit
	 * will do the right thing when called, including for C++
	 * d-tors.
	 */
	__onexitbegin = __onexitend = (_PVFV *)(-1);
	    
	dbgmsg("OK1b");

	/*
	 * Propogate the _fmode and _commode variables to the DLL
	 * (crash in crtdll.dll...?)
	 */
	//*_IMP___FMODE = _fmode;
	dbgmsg("OK1c");
	//*_IMP___COMMODE = _commode;
	dbgmsg("OK1d");
	
#ifdef _M_IX86
	/*
	 * Set the local copy of the Pentium FDIV adjustment flag
	 * (not supported by crtdll.dll)
	 */
	
	//_adjust_fdiv = * _imp___adjust_fdiv;
#endif  /* _M_IX86 */
	
	dbgmsg("OK2");

	/*
	 * Run the RTC initialization code for this DLL
	 */
#ifdef _RTC
	_RTC_Initialize();
#endif  /* _RTC */
	
	/*
	 * Call _setargv(), which will trigger a call to __setargv() if
	 * SETARGV.OBJ is linked with the EXE.  If SETARGV.OBJ is not
	 * linked with the EXE, a dummy _setargv() will be called.
	 */
#ifdef WPRFLAG
	//_wsetargv();
#else  /* WPRFLAG */
	//_setargv();
#endif  /* WPRFLAG */

	/*
	 * If the user has supplied a _matherr routine then set
	 * __pusermatherr to point to it.
	 */
	//            if ( !__defaultmatherr )
	//    __setusermatherr(_matherr);
	
#ifdef _M_IX86
	//_setdefaultprecision();
#endif  /* _M_IX86 */

	/*
	 * Do runtime startup initializers.
	 *
	 * Note: the only possible entry we'll be executing here is for
	 * __lconv_init, pulled in from charmax.obj only if the EXE was
	 * compiled with -J.  All other .CRT$XI* initializers are only
	 * run as part of the CRT itself, and so for the CRT DLL model
	 * are not found in the EXE.  For that reason, we call _initterm,
	 * not _initterm_e, because __lconv_init will never return failure,
	 * and _initterm_e is not exported from the CRT DLL.
	 *
	 * Note further that, when using the CRT DLL, executing the
	 * .CRT$XI* initializers is only done for an EXE, not for a DLL
	 * using the CRT DLL.  That is to make sure the -J setting for
	 * the EXE is not overriden by that of any DLL.
	 */
	//_initterm( __xi_a, __xi_z );

#ifdef _RTC
	atexit(_RTC_Terminate);
#endif  /* _RTC */

	/*
	 * Get the arguments for the call to main. Note this must be
	 * done explicitly, rather than as part of the dll's
	 * initialization, to implement optional expansion of wild
	 * card chars in filename args
	 */

	dbgmsg("OK3");

	//startinfo.newmode = 0;

#ifdef WPRFLAG
	_wcmdln = GetCommandLineW();
	argv = (_TSCHAR**)CommandLineToArgvW(_wcmdln, &argc);
	if (argv == NULL)
	  FatalAppExitA(0, "This application requires Windows NT.");

	_wpgmptr = (wchar_t*)argv[0];
	__wargv = (wchar_t**)argv;
	__argc = argc;
	_wenviron[0] = GetEnvironmentStringsW();
	while ((_wenviron[envp_count][0] != 0) &
	       (envp_count < MAX_WENVIRON_COUNT))
	  {
	    _wenviron[envp_count+1] = _wenviron[envp_count]+
	      wcslen(_wenviron[envp_count])+1;
	    envp_count++;
	  }
	
	if ((argv == NULL) | (envp_count >= MAX_WENVIRON_COUNT))
	  argret = -1;

	if (argret < 0)
	  _amsg_exit(_RT_SPACEARG);

	_wenviron[envp_count] = NULL;
	envp = (_TSCHAR**)_wenviron;

#else  /* WPRFLAG */
	argret = __GetMainArgs(&argc, &argv, &envp,
			       0, NULL /*&startinfo*/);

	if (argv == NULL)
	  _amsg_exit(_RT_SPACEARG);

	__argc = argc;
	__argv = argv;
	_environ = envp;
	_pgmptr = argv[0];
#endif
	dbgmsg("OK4");

	/*
	 * do C++ constructors (initializers) specific to this EXE
	 */
	//_initterm( __xc_a, __xc_z );
	
#ifdef _WINMAIN_
	/*
	 * Skip past program name (first token in command line).
	 * Check for and handle quoted program name.
	 */
#ifdef WPRFLAG
	/* OS may not support "W" flavors */

	if (_wcmdln == NULL)
	  FatalAppExitA(0, "This application requires Windows NT.");

	lpszCommandLine = (wchar_t *)_wcmdln;

#else  /* WPRFLAG */
	lpszCommandLine = (unsigned char *)_acmdln;
#endif  /* WPRFLAG */
	
	if ( *lpszCommandLine == DQUOTECHAR ) {
	  /*
	   * Scan, and skip over, subsequent characters until
	   * another double-quote or a null is encountered.
	   */
	  while ( *++lpszCommandLine && (*lpszCommandLine
					 != DQUOTECHAR) );
	  /*
	   * If we stopped on a double-quote (usual case), skip
	   * over it.
	   */
	  if ( *lpszCommandLine == DQUOTECHAR )
	    lpszCommandLine++;
	}

	while (*lpszCommandLine > SPACECHAR)
	  lpszCommandLine++;

	if (*lpszCommandLine >= SPACECHAR)
	  lpszCommandLine++;

	dbgmsg("OK5");

	/*
	 * Skip past any white space preceeding the second token.
	 */
	while (*lpszCommandLine && (*lpszCommandLine <= SPACECHAR)) {
	  lpszCommandLine++;
	}

	StartupInfo.dwFlags = 0;
	GetStartupInfo( &StartupInfo );

#ifdef WPRFLAG
	    __winitenv = (wchar_t**)envp;
	    exit(wWinMain(
#else  /* WPRFLAG */
            __initenv = envp;
	    exit(WinMain(
#endif  /* WPRFLAG */
                       GetModuleHandleA(NULL),
                       NULL,
                       (LPTSTR)lpszCommandLine,
                       StartupInfo.dwFlags & STARTF_USESHOWWINDOW
                        ? StartupInfo.wShowWindow
                        : SW_SHOWDEFAULT
		       ));

#else  /* _WINMAIN_ */

#ifdef WPRFLAG
	    dbgmsg("OK6");
            exit(wmain(argc, (wchar_t**)argv, (wchar_t**)envp));
#else  /* WPRFLAG */
	    dbgmsg("OK6");
            exit(main(argc, argv, envp));
#endif  /* WPRFLAG */

#endif  /* _WINMAIN_ */
}