/*********************************************************************** * GetDOSEnvironment (KERNEL.131) * * Note: the environment is allocated once, it doesn't track changes * made using the Win32 API. This shouldn't matter. * * Format of a 16-bit environment block: * ASCIIZ string 1 (xx=yy format) * ... * ASCIIZ string n * BYTE 0 * WORD 1 * ASCIIZ program name (e.g. C:\WINDOWS\SYSTEM\KRNL386.EXE) */ SEGPTR WINAPI GetDOSEnvironment16(void) { static const char ENV_program_name[] = "C:\\WINDOWS\\SYSTEM\\KRNL386.EXE"; static HGLOBAL16 handle; /* handle to the 16 bit environment */ if (!handle) { DWORD size; LPSTR p, env; p = env = GetEnvironmentStringsA(); while (*p) p += strlen(p) + 1; p++; /* skip last null */ size = (p - env) + sizeof(WORD) + sizeof(ENV_program_name); handle = GlobalAlloc16( GMEM_FIXED, size ); if (handle) { WORD one = 1; LPSTR env16 = GlobalLock16( handle ); memcpy( env16, env, p - env ); memcpy( env16 + (p - env), &one, sizeof(one)); memcpy( env16 + (p - env) + sizeof(WORD), ENV_program_name, sizeof(ENV_program_name)); GlobalUnlock16( handle ); } FreeEnvironmentStringsA( env ); } return WOWGlobalLock16( handle ); }
int main() { //Timer t; Environment env( GetEnvironmentStringsA(), false ); std::string compilerExecutable; PathList pathList; getPath( env, pathList ); if ( !findOnPath( pathList, "cl.exe", compilerExecutable ) ) { std::cerr << "Failed to locate executable 'cl.exe' on PATH.\n"; return -1; } bool const disableFallback = !!env.get( "BP_DISABLE_FALLBACK" ); llvm::Optional<std::string> const portNameVar( env.get( "BP_MANAGER_PORT" ) ); return distributedCompile( "msvc", compilerExecutable.c_str(), env, GetCommandLineA(), NULL, portNameVar ? portNameVar->data() : "default", disableFallback ? NULL : runLocallyFallback, const_cast<char *>( compilerExecutable.c_str() ) ); }
/* Windows does it differently, though arguably the most sanely. * GetEnvironmentStrings() returns a pointer to a block of * environment vars with a double null terminator: * Var1=Value1\0 * Var2=Value2\0 * ... * VarN=ValueN\0\0 * But because everyone else (ie POSIX) uses a vector of strings, we convert * to that format. Fortunately this is just a matter of making an array of * offsets into the environment block. * * Note that we have to call FreeEnvironmentStrings() at the end. * */ void getProgEnvv(int *out_envc, char **out_envv[]) { int envc, i; char *env; char *envp; char **envv; /* For now, use the 'A'nsi not 'W'ide variant. Note: corresponding Free below must use the same 'A'/'W' variant. */ env = GetEnvironmentStringsA(); envc = 0; for (envp = env; *envp != 0; envp += strlen(envp) + 1) { envc++; } envv = stgMallocBytes(sizeof(char*) * (envc+1), "getProgEnvv"); i = 0; for (envp = env; *envp != 0; envp += strlen(envp) + 1) { envv[i] = envp; i++; } /* stash whole env in last+1 entry */ envv[envc] = env; *out_envc = envc; *out_envv = envv; }
static jstring environmentBlock9x(JNIEnv *env) { int i; jmethodID String_init_ID = (*env)->GetMethodID(env, JNU_ClassString(env), "<init>", "([B)V"); jbyteArray bytes; jbyte *blockA = (jbyte *) GetEnvironmentStringsA(); if (blockA == NULL) { /* Both GetEnvironmentStringsW and GetEnvironmentStringsA * failed. Out of memory is our best guess. */ JNU_ThrowOutOfMemoryError(env, "GetEnvironmentStrings failed"); return NULL; } /* Don't search for "\0\0", since an empty environment block may legitimately consist of a single "\0". */ for (i = 0; blockA[i];) while (blockA[i++]) ; if ((bytes = (*env)->NewByteArray(env, i)) == NULL) return NULL; (*env)->SetByteArrayRegion(env, bytes, 0, i, blockA); FreeEnvironmentStringsA(blockA); return (*env)->NewObject(env, JNU_ClassString(env), String_init_ID, bytes); }
int main (void) { int argc; char **argv; char **envp; /* These variables are used by the WEL library */ ghInstance = GetModuleHandle(NULL); eif_hInstance = GetModuleHandle(NULL); eif_hPrevInstance = NULL; eif_lpCmdLine = GetCommandLine(); eif_nCmdShow = SW_SHOW; /* Initialization of the command line which is going to be passed to eiffel */ get_argcargv (&argc, &argv); /* We get ANSI version of environment variables */ envp = (char **) GetEnvironmentStringsA(); eif_alloc_init(); #ifdef EIF_THREADS eif_thr_init_root(); #endif { GTCX struct ex_vect *exvect; jmp_buf exenv; egc_init_plug(); initsig(); initstk(); exvect = exset((char *) 0, 0, (char *) 0); exvect->ex_jbuf = &exenv; if (setjmp(exenv)) failure(); eif_retrieve_root (&argc, argv); eif_rtinit(argc, argv, envp); eif_init_root(); egc_rcdt_init(); emain(argc, argv); free_argv (&argv); reclaim(); } FreeEnvironmentStringsA ((LPSTR) envp); exit(0); return 0; }
void InfoEnvironment() { char * env = NULL; if (NULL != (env = GetEnvironmentStringsA())) { uint32_t length = 0; ConsoleIOPrint("Environment :\n"); do { ConsoleIOPrintFormatted("%s\n", env); env += (length = xstrlen(env)) + 1; } while (length > 0); } }
extern "C" CDECL rust_str * rust_getcwd() { rust_task *task = rust_get_current_task(); LOG(task, task, "rust_getcwd()"); char cbuf[BUF_BYTES]; #if defined(__WIN32__) if (!_getcwd(cbuf, sizeof(cbuf))) { #else if (!getcwd(cbuf, sizeof(cbuf))) { #endif task->fail(); return NULL; } return make_str(task->kernel, cbuf, strlen(cbuf), "rust_str(getcwd)"); } #if defined(__WIN32__) extern "C" CDECL rust_vec_box * rust_env_pairs() { rust_task *task = rust_get_current_task(); size_t envc = 0; LPTCH ch = GetEnvironmentStringsA(); LPTCH c; for (c = ch; *c; c += strlen(c) + 1) { ++envc; } c = ch; rust_vec_box *v = (rust_vec_box *) task->kernel->malloc(vec_size<rust_vec_box*>(envc), "str vec interior"); v->body.fill = v->body.alloc = sizeof(rust_vec*) * envc; for (size_t i = 0; i < envc; ++i) { size_t n = strlen(c); rust_str *str = make_str(task->kernel, c, n, "str"); ((rust_str**)&v->body.data)[i] = str; c += n + 1; } if (ch) { FreeEnvironmentStrings(ch); } return v; } #else extern "C" CDECL rust_vec_box * rust_env_pairs() { rust_task *task = rust_get_current_task(); #ifdef __APPLE__ char **environ = *_NSGetEnviron(); #endif char **e = environ; size_t envc = 0; while (*e) { ++envc; ++e; } return make_str_vec(task->kernel, envc, environ); } #endif extern "C" CDECL void unsupervise() { rust_task *task = rust_get_current_task(); task->unsupervise(); }
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; }
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; }
/****************************************************************** * start_debugger * * Does the effective debugger startup according to 'format' */ static BOOL start_debugger(PEXCEPTION_POINTERS epointers, HANDLE hEvent) { OBJECT_ATTRIBUTES attr; UNICODE_STRING nameW; char *cmdline, *env, *p; HANDLE hDbgConf; DWORD bAuto = TRUE; PROCESS_INFORMATION info; STARTUPINFOA startup; char* format = NULL; BOOL ret = FALSE; char buffer[256]; static const WCHAR AeDebugW[] = {'M','a','c','h','i','n','e','\\', 'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', 'W','i','n','d','o','w','s',' ','N','T','\\', 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 'A','e','D','e','b','u','g',0}; static const WCHAR DebuggerW[] = {'D','e','b','u','g','g','e','r',0}; static const WCHAR AutoW[] = {'A','u','t','o',0}; format_exception_msg( epointers, buffer, sizeof(buffer) ); MESSAGE("wine: %s (thread %04x), starting debugger...\n", buffer, GetCurrentThreadId()); attr.Length = sizeof(attr); attr.RootDirectory = 0; attr.ObjectName = &nameW; attr.Attributes = 0; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; RtlInitUnicodeString( &nameW, AeDebugW ); if (!NtOpenKey( &hDbgConf, KEY_ALL_ACCESS, &attr )) { char buffer[64]; KEY_VALUE_PARTIAL_INFORMATION *info; DWORD format_size = 0; RtlInitUnicodeString( &nameW, DebuggerW ); if (NtQueryValueKey( hDbgConf, &nameW, KeyValuePartialInformation, NULL, 0, &format_size ) == STATUS_BUFFER_OVERFLOW) { char *data = HeapAlloc(GetProcessHeap(), 0, format_size); NtQueryValueKey( hDbgConf, &nameW, KeyValuePartialInformation, data, format_size, &format_size ); info = (KEY_VALUE_PARTIAL_INFORMATION *)data; RtlUnicodeToMultiByteSize( &format_size, (WCHAR *)info->Data, info->DataLength ); format = HeapAlloc( GetProcessHeap(), 0, format_size+1 ); RtlUnicodeToMultiByteN( format, format_size, NULL, (WCHAR *)info->Data, info->DataLength ); format[format_size] = 0; if (info->Type == REG_EXPAND_SZ) { char* tmp; /* Expand environment variable references */ format_size=ExpandEnvironmentStringsA(format,NULL,0); tmp=HeapAlloc(GetProcessHeap(), 0, format_size); ExpandEnvironmentStringsA(format,tmp,format_size); HeapFree(GetProcessHeap(), 0, format); format=tmp; } HeapFree( GetProcessHeap(), 0, data ); } RtlInitUnicodeString( &nameW, AutoW ); if (!NtQueryValueKey( hDbgConf, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer)-sizeof(WCHAR), &format_size )) { info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; if (info->Type == REG_DWORD) memcpy( &bAuto, info->Data, sizeof(DWORD) ); else if (info->Type == REG_SZ) { WCHAR *str = (WCHAR *)info->Data; str[info->DataLength/sizeof(WCHAR)] = 0; bAuto = atoiW( str ); } } NtClose(hDbgConf); } if (format) { cmdline = HeapAlloc(GetProcessHeap(), 0, strlen(format) + 2*20); sprintf(cmdline, format, GetCurrentProcessId(), hEvent); HeapFree(GetProcessHeap(), 0, format); } else { cmdline = HeapAlloc(GetProcessHeap(), 0, 80); sprintf(cmdline, "winedbg --auto %d %ld", GetCurrentProcessId(), (ULONG_PTR)hEvent); } if (!bAuto) { HMODULE mod = GetModuleHandleA( "user32.dll" ); MessageBoxA_funcptr pMessageBoxA = NULL; if (mod) pMessageBoxA = (MessageBoxA_funcptr)GetProcAddress( mod, "MessageBoxA" ); if (pMessageBoxA) { static const char msg[] = ".\nDo you wish to debug it?"; char buffer[256]; format_exception_msg( epointers, buffer, sizeof(buffer)-sizeof(msg) ); strcat( buffer, msg ); if (pMessageBoxA( 0, buffer, "Exception raised", MB_YESNO | MB_ICONHAND ) == IDNO) { TRACE("Killing process\n"); goto EXIT; } } } /* make WINEDEBUG empty in the environment */ env = GetEnvironmentStringsA(); for (p = env; *p; p += strlen(p) + 1) { if (!memcmp( p, "WINEDEBUG=", sizeof("WINEDEBUG=")-1 )) { char *next = p + strlen(p); char *end = next + 1; while (*end) end += strlen(end) + 1; memmove( p + sizeof("WINEDEBUG=") - 1, next, end + 1 - next ); break; } } TRACE("Starting debugger %s\n", debugstr_a(cmdline)); memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); startup.dwFlags = STARTF_USESHOWWINDOW; startup.wShowWindow = SW_SHOWNORMAL; ret = CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, env, NULL, &startup, &info); FreeEnvironmentStringsA( env ); if (ret) { /* wait for debugger to come up... */ HANDLE handles[2]; CloseHandle(info.hThread); handles[0]=hEvent; handles[1]=info.hProcess; WaitForMultipleObjects(2, handles, FALSE, INFINITE); CloseHandle(info.hProcess); } else ERR("Couldn't start debugger (%s) (%d)\n" "Read the Wine Developers Guide on how to set up winedbg or another debugger\n", debugstr_a(cmdline), GetLastError()); EXIT: HeapFree(GetProcessHeap(), 0, cmdline); return ret; }
static BOOL MZ_DoLoadImage( HANDLE hFile, LPCSTR filename, OverlayBlock *oblk, WORD par_env_seg ) { IMAGE_DOS_HEADER mz_header; DWORD image_start,image_size,min_size,max_size,avail; BYTE*psp_start,*load_start; LPSTR oldenv = 0; int x, old_com=0, alloc; SEGPTR reloc; WORD env_seg, load_seg, rel_seg, oldpsp_seg; DWORD len; if (DOSVM_psp) { /* DOS process already running, inherit from it */ PDB16* par_psp; alloc=0; oldpsp_seg = DOSVM_psp; if( !par_env_seg) { par_psp = (PDB16*)((DWORD)DOSVM_psp << 4); oldenv = (LPSTR)((DWORD)par_psp->environment << 4); } } else { /* allocate new DOS process, inheriting from Wine environment */ alloc=1; oldpsp_seg = 0; if( !par_env_seg) oldenv = GetEnvironmentStringsA(); } SetFilePointer(hFile,0,NULL,FILE_BEGIN); if ( !ReadFile(hFile,&mz_header,sizeof(mz_header),&len,NULL) || len != sizeof(mz_header) || mz_header.e_magic != IMAGE_DOS_SIGNATURE) { char *p = strrchr( filename, '.' ); if (!p || strcasecmp( p, ".com" )) /* check for .COM extension */ { SetLastError(ERROR_BAD_FORMAT); goto load_error; } old_com=1; /* assume .COM file */ image_start=0; image_size=GetFileSize(hFile,NULL); min_size=0x10000; max_size=0x100000; mz_header.e_crlc=0; mz_header.e_ss=0; mz_header.e_sp=0xFFFE; mz_header.e_cs=0; mz_header.e_ip=0x100; } else { /* calculate load size */ image_start=mz_header.e_cparhdr<<4; image_size=mz_header.e_cp<<9; /* pages are 512 bytes */ /* From Ralf Brown Interrupt List: If the word at offset 02h is 4, it should * be treated as 00h, since pre-1.10 versions of the MS linker set it that * way. */ if ((mz_header.e_cblp!=0)&&(mz_header.e_cblp!=4)) image_size-=512-mz_header.e_cblp; image_size-=image_start; min_size=image_size+((DWORD)mz_header.e_minalloc<<4)+(PSP_SIZE<<4); max_size=image_size+((DWORD)mz_header.e_maxalloc<<4)+(PSP_SIZE<<4); } if (alloc) MZ_InitMemory(); if (oblk) { /* load overlay into preallocated memory */ load_seg=oblk->load_seg; rel_seg=oblk->rel_seg; load_start=(LPBYTE)((DWORD)load_seg<<4); } else { /* allocate environment block */ if( par_env_seg) env_seg = par_env_seg; else env_seg=MZ_InitEnvironment(oldenv, filename); if( alloc && oldenv) FreeEnvironmentStringsA( oldenv); /* allocate memory for the executable */ TRACE("Allocating DOS memory (min=%ld, max=%ld)\n",min_size,max_size); avail=DOSMEM_Available(); if (avail<min_size) { ERR("insufficient DOS memory\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto load_error; } if (avail>max_size) avail=max_size; psp_start=DOSMEM_AllocBlock(avail,&DOSVM_psp); if (!psp_start) { ERR("error allocating DOS memory\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto load_error; } load_seg=DOSVM_psp+(old_com?0:PSP_SIZE); rel_seg=load_seg; load_start=psp_start+(PSP_SIZE<<4); MZ_CreatePSP(psp_start, env_seg, oldpsp_seg); } /* load executable image */ TRACE("loading DOS %s image, %08lx bytes\n",old_com?"COM":"EXE",image_size); SetFilePointer(hFile,image_start,NULL,FILE_BEGIN); if (!ReadFile(hFile,load_start,image_size,&len,NULL) || len != image_size) { /* check if this is due to the workaround for the pre-1.10 MS linker and we realy had only 4 bytes on the last page */ if (mz_header.e_cblp != 4 || image_size - len != 512 - 4) { SetLastError(ERROR_BAD_FORMAT); goto load_error; } } if (mz_header.e_crlc) { /* load relocation table */ TRACE("loading DOS EXE relocation table, %d entries\n",mz_header.e_crlc); /* FIXME: is this too slow without read buffering? */ SetFilePointer(hFile,mz_header.e_lfarlc,NULL,FILE_BEGIN); for (x=0; x<mz_header.e_crlc; x++) { if (!ReadFile(hFile,&reloc,sizeof(reloc),&len,NULL) || len != sizeof(reloc)) { SetLastError(ERROR_BAD_FORMAT); goto load_error; } *(WORD*)SEGPTR16(load_start,reloc)+=rel_seg; } } if (!oblk) { init_cs = load_seg+mz_header.e_cs; init_ip = mz_header.e_ip; init_ss = load_seg+mz_header.e_ss; init_sp = mz_header.e_sp; if (old_com){ /* .COM files exit with ret. Make sure they jump to psp start (=int 20) */ WORD* stack = PTR_REAL_TO_LIN(init_ss, init_sp); *stack = 0; } TRACE("entry point: %04x:%04x\n",init_cs,init_ip); } if (alloc && !MZ_InitTask()) { SetLastError(ERROR_GEN_FAILURE); return FALSE; } return TRUE; load_error: DOSVM_psp = oldpsp_seg; return FALSE; }