Пример #1
0
/******************************************************************
 *		FindDebugInfoFile (DBGHELP.@)
 *
 */
HANDLE WINAPI FindDebugInfoFile(PCSTR FileName, PCSTR SymbolPath, PSTR DebugFilePath)
{
    HANDLE      h;


    TRACE("(FileName = '%s', SymbolPath = '%s', DebugFilePath = %p)\n", FileName, SymbolPath, DebugFilePath);

    h = CreateFileA(FileName, GENERIC_READ, FILE_SHARE_READ, NULL,
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);


    if (h == INVALID_HANDLE_VALUE)
    {
        TRACE("file didn't exist in the current directory.  Trying search path '%s'\n", SymbolPath);
        
        if (!SearchPathA(SymbolPath, file_name(FileName), NULL, MAX_PATH, DebugFilePath, NULL)){
            TRACE("the symbol file '%s' wasn't found on the path '%s'\n", FileName, SymbolPath);
            return 0;
        }


        TRACE("the symbol file '%s' was found at '%s'\n", FileName, DebugFilePath);
        h = CreateFileA(DebugFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    }

    else{

        /* EWWWWWW!!!  no buffer size is known at this point!  VERY UNSAFE!! */
        strcpy(DebugFilePath, FileName);
    }

    return (h == INVALID_HANDLE_VALUE) ? 0 : h;
}
Пример #2
0
/***********************************************************************
 *              pif_cmd
 *
 * execute a pif file.
 */
static VOID pif_cmd( char *filename, char *cmdline)
{ 
    HANDLE hFile;
    char progpath[MAX_PATH];
    char buf[128];
    char progname[64];
    char title[31];
    char optparams[65];
    char startdir[65];
    char *p;
    int closeonexit;
    int textmode;
    if( (hFile = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ,
                    NULL, OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE)
    {
        WINE_ERR("open file %s failed\n", wine_dbgstr_a(filename));
        return;
    }
    if( !read_pif_file( hFile, progname, title, optparams, startdir,
                &closeonexit, &textmode)) {
        WINE_ERR( "failed to read %s\n", wine_dbgstr_a(filename));
        CloseHandle( hFile);
        sprintf( buf, "%s\nInvalid file format. Check your pif file.", 
                filename);
        MessageBoxA( NULL, buf, "16 bit DOS subsystem", MB_OK|MB_ICONWARNING);
        SetLastError( ERROR_BAD_FORMAT);
        return;
    }
    CloseHandle( hFile);
    if( (p = strrchr( progname, '.')) && !strcasecmp( p, ".bat"))
        WINE_FIXME(".bat programs in pif files are not supported.\n"); 
    /* first change dir, so the search below can start from there */
    if( startdir[0] && !SetCurrentDirectoryA( startdir)) {
        WINE_ERR("Cannot change directory %s\n", wine_dbgstr_a( startdir));
        sprintf( buf, "%s\nInvalid startup directory. Check your pif file.", 
                filename);
        MessageBoxA( NULL, buf, "16 bit DOS subsystem", MB_OK|MB_ICONWARNING);
    }
    /* search for the program */
    if( !SearchPathA( NULL, progname, NULL, MAX_PATH, progpath, NULL )) {
        sprintf( buf, "%s\nInvalid program file name. Check your pif file.", 
                filename);
        MessageBoxA( NULL, buf, "16 bit DOS subsystem", MB_OK|MB_ICONERROR);
        SetLastError( ERROR_FILE_NOT_FOUND);
        return;
    }
    if( textmode)
        if( AllocConsole())
            SetConsoleTitleA( title) ;
    /* if no arguments on the commandline, use them from the pif file */
    if( !cmdline[0] && optparams[0])
        cmdline = optparams;
    /* FIXME: do something with:
     * - close on exit
     * - graphic modes
     * - hot key's
     * - etc.
     */ 
    start_dos_exe( progpath, cmdline );
}
Пример #3
0
CURLcode FindWin32CACert(struct Configurable *config, const char *bundle_file)
{
  CURLcode result = CURLE_OK;

  /* search and set cert file only if libcurl supports SSL */
  if(curlinfo->features & CURL_VERSION_SSL) {

    DWORD res_len;
    DWORD buf_tchar_size = PATH_MAX + 1;
    DWORD buf_bytes_size = sizeof(TCHAR) * buf_tchar_size;
    char *ptr = NULL;

    char *buf = malloc(buf_bytes_size);
    if(!buf)
      return CURLE_OUT_OF_MEMORY;
    buf[0] = '\0';

    res_len = SearchPathA(NULL, bundle_file, NULL, buf_tchar_size, buf, &ptr);
    if(res_len > 0) {
      Curl_safefree(config->cacert);
      config->cacert = strdup(buf);
      if(!config->cacert)
        result = CURLE_OUT_OF_MEMORY;
    }

    Curl_safefree(buf);
  }

  return result;
}
Пример #4
0
/******************************************************************
 *		FindExecutableImage (DBGHELP.@)
 *
 */
HANDLE WINAPI FindExecutableImage(PCSTR FileName, PCSTR SymbolPath, PSTR ImageFilePath)
{
    HANDLE h;
    if (!SearchPathA(SymbolPath, FileName, NULL, MAX_PATH, ImageFilePath, NULL))
        return NULL;
    h = CreateFileA(ImageFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, 
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    return (h == INVALID_HANDLE_VALUE) ? NULL : h;
}
Пример #5
0
void GetLinkedModulesInfo(TCHAR *moduleName, CMString &buffer)
{
	HANDLE hDllFile = CreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hDllFile == INVALID_HANDLE_VALUE)
		return;

	HANDLE hDllMapping = CreateFileMapping(hDllFile, NULL, PAGE_READONLY, 0, 0, NULL);
	if (hDllMapping == INVALID_HANDLE_VALUE) {
		CloseHandle(hDllFile);
		return;
	}

	LPVOID dllAddr = MapViewOfFile(hDllMapping, FILE_MAP_READ, 0, 0, 0);

	static const TCHAR format[] = TEXT("    Plugin statically linked to missing module: %S\r\n");

	__try {
		PIMAGE_NT_HEADERS nthdrs = ImageNtHeader(dllAddr);

		ULONG tableSize;
		PIMAGE_IMPORT_DESCRIPTOR importData = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(dllAddr, FALSE,
			IMAGE_DIRECTORY_ENTRY_IMPORT, &tableSize);
		if (importData) {
			while (importData->Name) {
				char* moduleName = (char*)ImageRvaToVa(nthdrs, dllAddr, importData->Name, NULL);
				if (!SearchPathA(NULL, moduleName, NULL, NULL, 0, NULL))
					buffer.AppendFormat(format, moduleName);

				importData++; //go to next record
			}
		}

		bool found = false;
		PIMAGE_EXPORT_DIRECTORY exportData = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(dllAddr, FALSE,
			IMAGE_DIRECTORY_ENTRY_EXPORT, &tableSize);
		if (exportData) {
			ULONG* funcAddr = (ULONG*)ImageRvaToVa(nthdrs, dllAddr, exportData->AddressOfNames, NULL);
			for (unsigned i = 0; i < exportData->NumberOfNames && !found; ++i) {
				char* funcName = (char*)ImageRvaToVa(nthdrs, dllAddr, funcAddr[i], NULL);
				found = mir_strcmp(funcName, "MirandaPluginInfoEx") == 0 || mir_strcmp(funcName, "MirandaPluginInfo") == 0;
				if (mir_strcmp(funcName, "DatabasePluginInfo") == 0) {
					buffer.Append(TEXT("    This dll is a Miranda database plugin, another database is active right now\r\n"));
					found = true;
				}
			}
		}
		if (!found)
			buffer.Append(TEXT("    This dll is not a Miranda plugin and should be removed from plugins directory\r\n"));
	}
	__except (EXCEPTION_EXECUTE_HANDLER) {}

	UnmapViewOfFile(dllAddr);
	CloseHandle(hDllMapping);
	CloseHandle(hDllFile);
}
Пример #6
0
/******************************************************************
 *		FindExecutableImageEx (DBGHELP.@)
 *
 */
HANDLE WINAPI FindExecutableImageEx(PCSTR FileName, PCSTR SymbolPath, PSTR ImageFilePath,
                                    PFIND_EXE_FILE_CALLBACK Callback, PVOID user)
{
    HANDLE h;

    if (Callback) FIXME("Unsupported callback yet\n");
    if (!SearchPathA(SymbolPath, FileName, NULL, MAX_PATH, ImageFilePath, NULL))
        return NULL;
    h = CreateFileA(ImageFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    return (h == INVALID_HANDLE_VALUE) ? NULL : h;
}
Пример #7
0
/******************************************************************
 *		FindDebugInfoFile (DBGHELP.@)
 *
 */
HANDLE WINAPI FindDebugInfoFile(PCSTR FileName, PCSTR SymbolPath, PSTR DebugFilePath)
{
    HANDLE      h;

    h = CreateFileA(DebugFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (h == INVALID_HANDLE_VALUE)
    {
        if (!SearchPathA(SymbolPath, file_name(FileName), NULL, MAX_PATH, DebugFilePath, NULL))
            return NULL;
        h = CreateFileA(DebugFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    }
    return (h == INVALID_HANDLE_VALUE) ? NULL : h;
}
Пример #8
0
/******************************************************************
 *		FindExecutableImageEx (DBGHELP.@)
 *
 */
HANDLE WINAPI FindExecutableImageEx(PCSTR FileName, PCSTR SymbolPath, PSTR ImageFilePath,
                                    PFIND_EXE_FILE_CALLBACK Callback, PVOID user)
{
    HANDLE h;


    TRACE("(FileName = '%s', SymbolPath = '%s', ImageFilePath = %p, Callback = %p, user = %p)\n", FileName, SymbolPath, ImageFilePath, Callback, user);

    if (Callback)
        FIXME("Unsupported callback yet\n");


    if (!SearchPathA(SymbolPath, FileName, NULL, MAX_PATH, ImageFilePath, NULL)){
        ERR("the file '%s' was not found in the path '%s'\n", FileName, SymbolPath);
        return 0;
    }


    TRACE("found the file '%s' at '%s'\n", FileName, ImageFilePath);
    h = CreateFileA(ImageFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
                    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    return (h == INVALID_HANDLE_VALUE) ? 0 : h;
}
Пример #9
0
/***********************************************************************
 *           OpenFile   (KERNEL.74)
 *           OpenFileEx (KERNEL.360)
 */
HFILE16 WINAPI OpenFile16( LPCSTR name, OFSTRUCT *ofs, UINT16 mode )
{
    HFILE hFileRet;
    HANDLE handle;
    FILETIME filetime;
    WORD filedatetime[2];
    const char *p, *filename;

    if (!ofs) return HFILE_ERROR;

    TRACE("%s %s %s %s%s%s%s%s%s%s%s%s\n",debugstr_a(name),
          ((mode & 0x3 )==OF_READ)?"OF_READ":
          ((mode & 0x3 )==OF_WRITE)?"OF_WRITE":
          ((mode & 0x3 )==OF_READWRITE)?"OF_READWRITE":"unknown",
          ((mode & 0x70 )==OF_SHARE_COMPAT)?"OF_SHARE_COMPAT":
          ((mode & 0x70 )==OF_SHARE_DENY_NONE)?"OF_SHARE_DENY_NONE":
          ((mode & 0x70 )==OF_SHARE_DENY_READ)?"OF_SHARE_DENY_READ":
          ((mode & 0x70 )==OF_SHARE_DENY_WRITE)?"OF_SHARE_DENY_WRITE":
          ((mode & 0x70 )==OF_SHARE_EXCLUSIVE)?"OF_SHARE_EXCLUSIVE":"unknown",
          ((mode & OF_PARSE )==OF_PARSE)?"OF_PARSE ":"",
          ((mode & OF_DELETE )==OF_DELETE)?"OF_DELETE ":"",
          ((mode & OF_VERIFY )==OF_VERIFY)?"OF_VERIFY ":"",
          ((mode & OF_SEARCH )==OF_SEARCH)?"OF_SEARCH ":"",
          ((mode & OF_CANCEL )==OF_CANCEL)?"OF_CANCEL ":"",
          ((mode & OF_CREATE )==OF_CREATE)?"OF_CREATE ":"",
          ((mode & OF_PROMPT )==OF_PROMPT)?"OF_PROMPT ":"",
          ((mode & OF_EXIST )==OF_EXIST)?"OF_EXIST ":"",
          ((mode & OF_REOPEN )==OF_REOPEN)?"OF_REOPEN ":""
        );

    if (mode & OF_PARSE)
    {
        OpenFile( name, ofs, mode );
        return 0;
    }

    if (mode & OF_CREATE)
    {
        handle = (HANDLE)OpenFile( name, ofs, mode );
        if (handle == (HANDLE)HFILE_ERROR) goto error;
    }
    else
    {
        ofs->cBytes = sizeof(OFSTRUCT);
        ofs->nErrCode = 0;
        if (mode & OF_REOPEN) name = ofs->szPathName;

        if (!name) return HFILE_ERROR;

        /* the watcom 10.6 IDE relies on a valid path returned in ofs->szPathName
           Are there any cases where getting the path here is wrong?
           Uwe Bonnes 1997 Apr 2 */
        if (!GetFullPathNameA( name, sizeof(ofs->szPathName), ofs->szPathName, NULL )) goto error;

        /* If OF_SEARCH is set, ignore the given path */

        filename = name;
        if ((mode & OF_SEARCH) && !(mode & OF_REOPEN))
        {
            /* First try the file name as is */
            if (GetFileAttributesA( filename ) != INVALID_FILE_ATTRIBUTES) filename = NULL;
            else
            {
                /* Now remove the path */
                if (filename[0] && (filename[1] == ':')) filename += 2;
                if ((p = strrchr( filename, '\\' ))) filename = p + 1;
                if ((p = strrchr( filename, '/' ))) filename = p + 1;
                if (!filename[0])
                {
                    SetLastError( ERROR_FILE_NOT_FOUND );
                    goto error;
                }
            }
        }

        /* Now look for the file */

        if (filename)
        {
            BOOL found;
            char *path = get_search_path();

            if (!path) goto error;
            found = SearchPathA( path, filename, NULL, sizeof(ofs->szPathName),
                                 ofs->szPathName, NULL );
            HeapFree( GetProcessHeap(), 0, path );
            if (!found) goto error;
        }

        TRACE("found %s\n", debugstr_a(ofs->szPathName) );

        if (mode & OF_DELETE)
        {
            if (!DeleteFileA( ofs->szPathName )) goto error;
            TRACE("(%s): OF_DELETE return = OK\n", name);
            return 1;
        }

        handle = (HANDLE)_lopen( ofs->szPathName, mode );
        if (handle == INVALID_HANDLE_VALUE) goto error;

        GetFileTime( handle, NULL, NULL, &filetime );
        FileTimeToDosDateTime( &filetime, &filedatetime[0], &filedatetime[1] );
        if ((mode & OF_VERIFY) && (mode & OF_REOPEN))
        {
            if (ofs->Reserved1 != filedatetime[0] || ofs->Reserved2 != filedatetime[1] )
            {
                CloseHandle( handle );
                WARN("(%s): OF_VERIFY failed\n", name );
                /* FIXME: what error here? */
                SetLastError( ERROR_FILE_NOT_FOUND );
                goto error;
            }
        }
        ofs->Reserved1 = filedatetime[0];
        ofs->Reserved2 = filedatetime[1];
    }

    TRACE("(%s): OK, return = %p\n", name, handle );
    hFileRet = Win32HandleToDosFileHandle( handle );
    if (hFileRet == HFILE_ERROR16) goto error;
    if (mode & OF_EXIST) _lclose16( hFileRet ); /* Return the handle, but close it first */
    return hFileRet;

error:  /* We get here if there was an error opening the file */
    ofs->nErrCode = GetLastError();
    WARN("(%s): return = HFILE_ERROR error= %d\n", name,ofs->nErrCode );
    return HFILE_ERROR16;
}
Пример #10
0
/***********************************************************************
 *		BindImageEx (IMAGEHLP.@)
 *
 * Compute the virtual address of each function imported by a PE image
 *
 * PARAMS
 *
 *   Flags         [in] Bind options
 *   ImageName     [in] File name of the image to be bound
 *   DllPath       [in] Root of the fallback search path in case the ImageName file cannot be opened
 *   SymbolPath    [in] Symbol file root search path
 *   StatusRoutine [in] Pointer to a status routine which will be called during the binding process
 *
 * RETURNS
 *   Success: TRUE
 *   Failure: FALSE
 *
 * NOTES
 *  Binding is not implemented yet, so far this function only enumerates
 *  all imported dlls/functions and returns TRUE.
 */
BOOL WINAPI BindImageEx(
  DWORD Flags, PCSTR ImageName, PCSTR DllPath, PCSTR SymbolPath,
  PIMAGEHLP_STATUS_ROUTINE StatusRoutine)
{
    LOADED_IMAGE loaded_image;
    const IMAGE_IMPORT_DESCRIPTOR *import_desc;
    ULONG size;

    FIXME("(%d, %s, %s, %s, %p): semi-stub\n",
        Flags, debugstr_a(ImageName), debugstr_a(DllPath),
        debugstr_a(SymbolPath), StatusRoutine
    );

    if (!(MapAndLoad(ImageName, DllPath, &loaded_image, TRUE, TRUE))) return FALSE;

    if (!(import_desc = RtlImageDirectoryEntryToData((HMODULE)loaded_image.MappedAddress, FALSE,
                                                     IMAGE_DIRECTORY_ENTRY_IMPORT, &size)))
    {
        UnMapAndLoad(&loaded_image);
        return TRUE; /* No imported modules means nothing to bind, so we're done. */
    }

    /* FIXME: Does native imagehlp support both 32-bit and 64-bit PE executables? */
#ifdef _WIN64
    if (loaded_image.FileHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)
#else
    if (loaded_image.FileHeader->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC)
#endif
    {
        FIXME("Wrong architecture in PE header, unable to enumerate imports\n");
        UnMapAndLoad(&loaded_image);
        return TRUE;
    }

    for (; import_desc->Name && import_desc->FirstThunk; ++import_desc)
    {
        IMAGE_THUNK_DATA *thunk;
        char dll_fullname[MAX_PATH];
        const char *dll_name;

        if (!(dll_name = ImageRvaToVa(loaded_image.FileHeader, loaded_image.MappedAddress,
                                      import_desc->Name, 0)))
        {
            UnMapAndLoad(&loaded_image);
            SetLastError(ERROR_INVALID_ACCESS); /* FIXME */
            return FALSE;
        }

        if (StatusRoutine)
            StatusRoutine(BindImportModule, ImageName, dll_name, 0, 0);

        if (!SearchPathA(DllPath, dll_name, 0, sizeof(dll_fullname), dll_fullname, 0))
        {
            UnMapAndLoad(&loaded_image);
            SetLastError(ERROR_FILE_NOT_FOUND);
            return FALSE;
        }

        if (!(thunk = ImageRvaToVa(loaded_image.FileHeader, loaded_image.MappedAddress,
                                   import_desc->OriginalFirstThunk ? import_desc->OriginalFirstThunk :
                                   import_desc->FirstThunk, 0)))
        {
            ERR("Can't grab thunk data of %s, going to next imported DLL\n", dll_name);
            continue;
        }

        for (; thunk->u1.Ordinal; ++thunk)
        {
            /* Ignoring ordinal imports for now */
            if(!IMAGE_SNAP_BY_ORDINAL(thunk->u1.Ordinal))
            {
                IMAGE_IMPORT_BY_NAME *iibn;

                if (!(iibn = ImageRvaToVa(loaded_image.FileHeader, loaded_image.MappedAddress,
                                          thunk->u1.AddressOfData, 0)))
                {
                    ERR("Can't grab import by name info, skipping to next ordinal\n");
                    continue;
                }

                if (StatusRoutine)
                    StatusRoutine(BindImportProcedure, ImageName, dll_fullname, 0, (ULONG_PTR)iibn->Name);
            }
        }
    }

    UnMapAndLoad(&loaded_image);
    return TRUE;
}
Пример #11
0
/*
  find an executable by name in $PATH. Exclude any that are links to exclude_name 
*/
char *find_executable(const char *name, const char *exclude_name)
{
#if _WIN32
	DWORD ret;
	char namebuf[MAX_PATH];

        ret = SearchPathA(getenv("CCACHE_PATH"), name, ".exe",
                          sizeof(namebuf), namebuf, NULL);
        if (ret != 0) {
        	return x_strdup(namebuf);
        }

        return NULL;
#else
	char *path;
	char *tok;
	struct stat st1, st2;

	if (*name == '/') {
		return x_strdup(name);
	}

	path = getenv("CCACHE_PATH");
	if (!path) {
		path = getenv("PATH");
	}
	if (!path) {
		cc_log("no PATH variable!?\n");
		return NULL;
	}

	path = x_strdup(path);
	
	/* search the path looking for the first compiler of the right name
	   that isn't us */
	for (tok=strtok(path,":"); tok; tok = strtok(NULL, ":")) {
		char *fname;
		x_asprintf(&fname, "%s/%s", tok, name);
		/* look for a normal executable file */
		if (access(fname, X_OK) == 0 &&
		    lstat(fname, &st1) == 0 &&
		    stat(fname, &st2) == 0 &&
		    S_ISREG(st2.st_mode)) {
			/* if its a symlink then ensure it doesn't
                           point at something called exclude_name */
			if (S_ISLNK(st1.st_mode)) {
				char *buf = x_realpath(fname);
				if (buf) {
					char *p = str_basename(buf);
					if (strcmp(p, exclude_name) == 0) {
						/* its a link to "ccache" ! */
						free(p);
						free(buf);
						continue;
					}
					free(buf);
					free(p);
				}
			}

			/* found it! */
			free(path);
			return fname;
		}
		free(fname);
	}

	return NULL;
#endif
}
Пример #12
0
/***********************************************************************
 *           main
 */
int main( int argc, char *argv[] )
{
    DWORD count;
    HINSTANCE16 instance;
    LOADPARAMS16 params;
    WORD showCmd[2];
    char buffer[MAX_PATH];
    STARTUPINFOA info;
    char *cmdline, *appname, **first_arg;
    char *p;

    if (!argv[1]) usage();

    if (!strcmp( argv[1], "--app-name" ))
    {
        if (!(appname = argv[2])) usage();
        first_arg = argv + 3;
    }
    else
    {
        if (!SearchPathA( NULL, argv[1], ".exe", sizeof(buffer), buffer, NULL ))
        {
            WINE_MESSAGE( "winevdm: unable to exec '%s': file not found\n", argv[1] );
            ExitProcess(1);
        }
        appname = buffer;
        first_arg = argv + 1;
    }

    if (*first_arg) first_arg++;  /* skip program name */
    cmdline = build_command_line( first_arg );

    if (WINE_TRACE_ON(winevdm))
    {
        int i;
        WINE_TRACE( "GetCommandLine = '%s'\n", GetCommandLineA() );
        WINE_TRACE( "appname = '%s'\n", appname );
        WINE_TRACE( "cmdline = '%.*s'\n", cmdline[0], cmdline+1 );
        for (i = 0; argv[i]; i++) WINE_TRACE( "argv[%d]: '%s'\n", i, argv[i] );
    }

    GetStartupInfoA( &info );
    showCmd[0] = 2;
    showCmd[1] = (info.dwFlags & STARTF_USESHOWWINDOW) ? info.wShowWindow : SW_SHOWNORMAL;

    params.hEnvironment = 0;
    params.cmdLine = MapLS( cmdline );
    params.showCmd = MapLS( showCmd );
    params.reserved = 0;

    RestoreThunkLock(1);  /* grab the Win16 lock */

    /* some programs assume mmsystem is always present */
    LoadLibrary16( "gdi.exe" );
    LoadLibrary16( "user.exe" );
    LoadLibrary16( "mmsystem.dll" );

    if ((instance = LoadModule16( appname, &params )) < 32)
    {
        if (instance == 11)
        {
            /* first see if it is a .pif file */
            if( ( p = strrchr( appname, '.' )) && !strcasecmp( p, ".pif"))
                pif_cmd( appname, cmdline + 1);
            else
            {
                /* try DOS format */
                /* loader expects arguments to be regular C strings */
                start_dos_exe( appname, cmdline + 1 );
            }
            /* if we get back here it failed */
            instance = GetLastError();
        }

        WINE_MESSAGE( "winevdm: can't exec '%s': ", appname );
        switch (instance)
        {
        case  2: WINE_MESSAGE("file not found\n" ); break;
        case 11: WINE_MESSAGE("invalid program file\n" ); break;
        default: WINE_MESSAGE("error=%d\n", instance ); break;
        }
        ExitProcess(instance);
    }

    /* wait forever; the process will be killed when the last task exits */
    ReleaseThunkLock( &count );
    Sleep( INFINITE );
    return 0;
}
Пример #13
0
static BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s)
{
    switch (action) {
    case ACTION_ADD: {
            CHAR filename[MAX_PATH];
            FILE *reg_file;

            get_file_name(&s, filename);
            if (!filename[0]) {
                fprintf(stderr,"%s: No file name was specified\n", getAppName());
                fprintf(stderr,usage);
                exit(1);
            }

            while(filename[0]) {
                char* realname = NULL;

                if (strcmp(filename, "-") == 0)
                {
                    reg_file = stdin;
                }
                else
                {
                    int size;

                    size = SearchPathA(NULL, filename, NULL, 0, NULL, NULL);
                    if (size > 0)
                    {
                        realname = HeapAlloc(GetProcessHeap(), 0, size);
                        size = SearchPathA(NULL, filename, NULL, size, realname, NULL);
                    }
                    if (size == 0)
                    {
                        fprintf(stderr, "%s: File not found \"%s\" (%d)\n",
                                getAppName(), filename, GetLastError());
                        exit(1);
                    }
                    reg_file = fopen(realname, "r");
                    if (reg_file == NULL)
                    {
                        perror("");
                        fprintf(stderr, "%s: Can't open file \"%s\"\n", getAppName(), filename);
                        exit(1);
                    }
                }
                import_registry_file(reg_file);
                if (realname)
                {
                    HeapFree(GetProcessHeap(),0,realname);
                    fclose(reg_file);
                }
                get_file_name(&s, filename);
            }
            break;
        }
    case ACTION_DELETE: {
            CHAR reg_key_name[KEY_MAX_LEN];

            get_file_name(&s, reg_key_name);
            if (!reg_key_name[0]) {
                fprintf(stderr,"%s: No registry key was specified for removal\n",
                        getAppName());
                fprintf(stderr,usage);
                exit(1);
            } else
            {
                WCHAR* reg_key_nameW = GetWideString(reg_key_name);
                delete_registry_key(reg_key_nameW);
                HeapFree(GetProcessHeap(), 0, reg_key_nameW);
            }
            break;
        }
    case ACTION_EXPORT: {
            CHAR filename[MAX_PATH];
            WCHAR* filenameW;

            filename[0] = '\0';
            get_file_name(&s, filename);
            if (!filename[0]) {
                fprintf(stderr,"%s: No file name was specified\n", getAppName());
                fprintf(stderr,usage);
                exit(1);
            }

            filenameW = GetWideString(filename);
            if (s[0]) {
                CHAR reg_key_name[KEY_MAX_LEN];
                WCHAR* reg_key_nameW;

                get_file_name(&s, reg_key_name);
                reg_key_nameW = GetWideString(reg_key_name);
                export_registry_key(filenameW, reg_key_nameW, REG_FORMAT_4);
                HeapFree(GetProcessHeap(), 0, reg_key_nameW);
            } else {
                export_registry_key(filenameW, NULL, REG_FORMAT_4);
            }
            HeapFree(GetProcessHeap(), 0, filenameW);
            break;
        }
    default:
        fprintf(stderr,"%s: Unhandled action!\n", getAppName());
        exit(1);
        break;
    }
    return TRUE;
}
Пример #14
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;
}
Пример #15
0
HINSTANCE HookWindow(HWND hWnd, DWORD dwProcessId, int data)
{
   const int cbCodeSize = ((LPBYTE)AfterRemoteStartup - (LPBYTE)RemoteStartup);
	const DWORD cbMemSize = cbCodeSize + sizeof(RemoteStartupArgs) + 3;
   HANDLE hProcess;
	HINSTANCE hinstKrnl = GetModuleHandle("Kernel32");
	PDWORD pdwCodeRemote = NULL;
   RemoteStartupArgs args;
   RemoteStartupArgs * pArgsRemote;
	DWORD dwNumBytesXferred = 0;
	HANDLE hThread = NULL;
   DWORD dwOldProtect;
   HINSTANCE res;

   hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
   if (!hProcess)
      return NULL;

   //Allocate some memory for our function and its argument
	pdwCodeRemote = (PDWORD) AllocProcessMemory(hProcess, cbMemSize);
	if (!pdwCodeRemote)
   {
      CloseHandle(hProcess);
      return NULL;
   }

	// Change the page protection of the allocated memory to executable, read, and write.
	if (!VirtualProtectEx(hProcess, pdwCodeRemote, cbMemSize, PAGE_EXECUTE_READWRITE, &dwOldProtect))
   {
      FreeProcessMemory(hProcess, pdwCodeRemote);
      CloseHandle(hProcess);
      return NULL;
   }

	// Write a copy of the function to the remote process.
   if (!WriteProcessMemory(hProcess, pdwCodeRemote, (LPVOID)RemoteStartup, cbCodeSize, &dwNumBytesXferred))
   {
      FreeProcessMemory(hProcess, pdwCodeRemote);
      CloseHandle(hProcess);
      return NULL;
   }

   // Initialize the arguments
   args.fnLoadLibrary = (HINSTANCE (WINAPI *)(LPCTSTR))
                          GetProcAddress(hinstKrnl, "LoadLibraryA");
   args.fnFreeLibrary = (BOOL (WINAPI *)(HINSTANCE))
                          GetProcAddress(hinstKrnl, "FreeLibrary");
   args.fnGetProcAddress = (FARPROC (WINAPI *)(HINSTANCE,LPCSTR))GetProcAddress(hinstKrnl, "GetProcAddress");
   args.hWnd = hWnd;
   args.data = data;
   args.fnIndex = 0x1;
   DWORD result = SearchPathA(NULL, "HookDLL.dll", NULL, MAX_PATH, args.pbLibFile, NULL);
   if ((result < 0) || (result > MAX_PATH))
   {
      FreeProcessMemory(hProcess, pdwCodeRemote);
      CloseHandle(hProcess);
      return NULL;
   }

	// Write a copy of the arguments to the remote process (the structure MUST start on a 32-bit bourdary)
   pArgsRemote = (RemoteStartupArgs*)(pdwCodeRemote + ((cbCodeSize + 4) & ~3));
   if (!WriteProcessMemory(hProcess, pArgsRemote,	&args, sizeof(args), &dwNumBytesXferred))
   {
      FreeProcessMemory(hProcess, pdwCodeRemote);
      CloseHandle(hProcess);
      return NULL;
   }

   //Run the remote function
	hThread = CreateRemoteThread(hProcess, NULL, 10000, (LPTHREAD_START_ROUTINE)pdwCodeRemote, pArgsRemote, 0, NULL);
	if (hThread == NULL)
   {
      FreeProcessMemory(hProcess, pdwCodeRemote);
      CloseHandle(hProcess);
      return NULL;
   }

   //Wait till it returns, then get the result
	WaitForSingleObject(hThread, INFINITE);
   GetExitCodeThread(hThread, (PDWORD) &res);
	
   //Do some cleanup
   CloseHandle(hThread);
   FreeProcessMemory(hProcess, pdwCodeRemote);
   CloseHandle(hProcess);

   return res;
}
Пример #16
0
/***********************************************************************
 *		MapAndLoad (IMAGEHLP.@)
 */
BOOL WINAPI MapAndLoad(PCSTR pszImageName, PCSTR pszDllPath, PLOADED_IMAGE pLoadedImage,
                       BOOL bDotDll, BOOL bReadOnly)
{
    CHAR szFileName[MAX_PATH];
    HANDLE hFile = INVALID_HANDLE_VALUE;
    HANDLE hFileMapping = NULL;
    PVOID mapping = NULL;
    PIMAGE_NT_HEADERS pNtHeader = NULL;

    TRACE("(%s, %s, %p, %d, %d)\n",
          pszImageName, pszDllPath, pLoadedImage, bDotDll, bReadOnly);

    if (!SearchPathA(pszDllPath, pszImageName, bDotDll ? ".DLL" : ".EXE",
                     sizeof(szFileName), szFileName, NULL))
    {
        SetLastError(ERROR_FILE_NOT_FOUND);
        goto Error;
    }

    hFile = CreateFileA(szFileName,
                        GENERIC_READ | (bReadOnly ? 0 : GENERIC_WRITE),
                        FILE_SHARE_READ,
                        NULL, OPEN_EXISTING, 0, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        WARN("CreateFile: Error = %d\n", GetLastError());
        goto Error;
    }

    hFileMapping = CreateFileMappingA(hFile, NULL, 
                                      (bReadOnly ? PAGE_READONLY : PAGE_READWRITE) | SEC_COMMIT,
                                      0, 0, NULL);
    if (!hFileMapping)
    {
        WARN("CreateFileMapping: Error = %d\n", GetLastError());
        goto Error;
    }

    mapping = MapViewOfFile(hFileMapping, bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, 0, 0);
    CloseHandle(hFileMapping);
    if (!mapping)
    {
        WARN("MapViewOfFile: Error = %d\n", GetLastError());
        goto Error;
    }

    if (!(pNtHeader = RtlImageNtHeader(mapping)))
    {
        WARN("Not an NT header\n");
        UnmapViewOfFile(mapping);
        goto Error;
    }

    pLoadedImage->ModuleName       = HeapAlloc(GetProcessHeap(), 0,
                                               strlen(szFileName) + 1);
    if (pLoadedImage->ModuleName) strcpy(pLoadedImage->ModuleName, szFileName);
    pLoadedImage->hFile            = hFile;
    pLoadedImage->MappedAddress    = mapping;
    pLoadedImage->FileHeader       = pNtHeader;
    pLoadedImage->Sections         = (PIMAGE_SECTION_HEADER)
        ((LPBYTE) &pNtHeader->OptionalHeader +
         pNtHeader->FileHeader.SizeOfOptionalHeader);
    pLoadedImage->NumberOfSections = pNtHeader->FileHeader.NumberOfSections;
    pLoadedImage->SizeOfImage      = GetFileSize(hFile, NULL);
    pLoadedImage->Characteristics  = pNtHeader->FileHeader.Characteristics;
    pLoadedImage->LastRvaSection   = pLoadedImage->Sections;

    pLoadedImage->fSystemImage     = FALSE; /* FIXME */
    pLoadedImage->fDOSImage        = FALSE; /* FIXME */

    pLoadedImage->Links.Flink      = &pLoadedImage->Links;
    pLoadedImage->Links.Blink      = &pLoadedImage->Links;

    return TRUE;

Error:
    if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
    return FALSE;
}
Пример #17
0
  //----------------------------------------------------------------------
  HRESULT create_dia_source()
  {
    HRESULT hr;
    // VC80/90 CRT installs msdiaNN.dll in this folder:
    // "C:\Program Files (x86)\Common Files\microsoft shared\VC"
    char common_files[QMAXPATH];
    qstring vc_shared;
    if ( get_special_folder(CSIDL_PROGRAM_FILES_COMMON, common_files, sizeof(common_files)) )
    {
      vc_shared = common_files;
      vc_shared.append("\\Microsoft Shared\\VC");
    }

    for ( size_t i=0; i < qnumber(g_msdiav); i++ )
    {
      // Try to create using CoCreateInstance()
      hr = CoCreateInstance(*g_msdiav[i],
        NULL,
        CLSCTX_INPROC_SERVER,
        __uuidof(IDiaDataSource),
        (void**)&pSource);

      // Try to create with CoCreateInstanceNoReg()
      if ( FAILED(hr) )
      {
        // Search for this interface in DIA dlls
        char path[QMAXPATH];
        if ( !search_path(g_diadlls[i], path, sizeof(path), false)
          && (vc_shared.empty() || SearchPathA(vc_shared.c_str(), g_diadlls[i], NULL, qnumber(path), path, NULL) == 0) )
          continue;

        for ( size_t j=0; j < qnumber(g_msdiav); j++ )
        {
          hr = CoCreateInstanceNoReg(
            path,
            *g_msdiav[j],
            NULL,
            __uuidof(IDiaDataSource),
            (void**)&pSource,
            &dia_hmod);

          if ( SUCCEEDED(hr) )
          {
            static bool displayed = false;
            if ( !displayed )
            {
              displayed = true;
              msg("PDB: using DIA dll \"%s\"\n", path);
            }
            i = j;
            break;
          }
        }
      }

      if ( SUCCEEDED(hr) )
      {
        dia_ver = g_diaver[i];
        static bool displayed = false;
        if ( !displayed )
        {
          displayed = true;
          msg("PDB: DIA interface version %d.%d\n", dia_ver/100, dia_ver%100);
        }
        return hr;
      }
    }
    return E_NOINTERFACE;
  }
Пример #18
0
pid_t
__archive_create_child(const char *cmd, int *child_stdin, int *child_stdout)
{
	HANDLE childStdout[2], childStdin[2],childStderr;
	SECURITY_ATTRIBUTES secAtts;
	STARTUPINFOA staInfo;
	PROCESS_INFORMATION childInfo;
	struct archive_string cmdline;
	struct archive_string fullpath;
	struct archive_cmdline *acmd;
	char *arg0, *ext;
	int i, l;
	DWORD fl, fl_old;

	childStdout[0] = childStdout[1] = INVALID_HANDLE_VALUE;
	childStdin[0] = childStdin[1] = INVALID_HANDLE_VALUE;
	childStderr = INVALID_HANDLE_VALUE;
	archive_string_init(&cmdline);
	archive_string_init(&fullpath);

	acmd = __archive_cmdline_allocate();
	if (acmd == NULL)
		goto fail;
	if (__archive_cmdline_parse(acmd, cmd) != ARCHIVE_OK)
		goto fail;

	/*
	 * Search the full path of 'path'.
	 * NOTE: This does not need if we give CreateProcessA 'path' as
	 * a part of the cmdline and give CreateProcessA NULL as first
	 * parameter, but I do not like that way.
	 */
	ext = strrchr(acmd->path, '.');
	if (ext == NULL || strlen(ext) > 4)
		/* 'path' does not have a proper extension, so we have to
		 * give SearchPath() ".exe" as the extension. */
		ext = ".exe";
	else
		ext = NULL;/* 'path' has an extension. */

	fl = MAX_PATH;
	do {
		if (archive_string_ensure(&fullpath, fl) == NULL)
			goto fail;
		fl_old = fl;
		fl = SearchPathA(NULL, acmd->path, ext, fl, fullpath.s,
			&arg0);
	} while (fl != 0 && fl > fl_old);
	if (fl == 0)
		goto fail;

	/*
	 * Make a command line.
	 */
	for (l = 0, i = 0;  acmd->argv[i] != NULL; i++) {
		if (i == 0)
			continue;
		l += (int)strlen(acmd->argv[i]) + 1;
	}
	if (archive_string_ensure(&cmdline, l + 1) == NULL)
		goto fail;
	for (i = 0;  acmd->argv[i] != NULL; i++) {
		if (i == 0) {
			const char *p, *sp;

			if ((p = strchr(acmd->argv[i], '/')) != NULL ||
			    (p = strchr(acmd->argv[i], '\\')) != NULL)
				p++;
			else
				p = acmd->argv[i];
			if ((sp = strchr(p, ' ')) != NULL)
				archive_strappend_char(&cmdline, '"');
			archive_strcat(&cmdline, p);
			if (sp != NULL)
				archive_strappend_char(&cmdline, '"');
		} else {
			archive_strappend_char(&cmdline, ' ');
			archive_strcat(&cmdline, acmd->argv[i]);
		}
	}
	if (i <= 1) {
		const char *sp;

		if ((sp = strchr(arg0, ' ')) != NULL)
			archive_strappend_char(&cmdline, '"');
		archive_strcat(&cmdline, arg0);
		if (sp != NULL)
			archive_strappend_char(&cmdline, '"');
	}

	secAtts.nLength = sizeof(SECURITY_ATTRIBUTES);
	secAtts.bInheritHandle = TRUE;
	secAtts.lpSecurityDescriptor = NULL;
	if (CreatePipe(&childStdout[0], &childStdout[1], &secAtts, 0) == 0)
		goto fail;
	if (!SetHandleInformation(childStdout[0], HANDLE_FLAG_INHERIT, 0))
		goto fail;
	if (CreatePipe(&childStdin[0], &childStdin[1], &secAtts, 0) == 0)
		goto fail;
	if (!SetHandleInformation(childStdin[1], HANDLE_FLAG_INHERIT, 0))
		goto fail;
	if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_ERROR_HANDLE),
	    GetCurrentProcess(), &childStderr, 0, TRUE,
	    DUPLICATE_SAME_ACCESS) == 0)
		goto fail;

	memset(&staInfo, 0, sizeof(staInfo));
	staInfo.cb = sizeof(staInfo);
	staInfo.hStdError = childStderr;
	staInfo.hStdOutput = childStdout[1];
	staInfo.hStdInput = childStdin[0];
	staInfo.wShowWindow = SW_HIDE;
	staInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
	if (CreateProcessA(fullpath.s, cmdline.s, NULL, NULL, TRUE, 0,
	      NULL, NULL, &staInfo, &childInfo) == 0)
		goto fail;
	WaitForInputIdle(childInfo.hProcess, INFINITE);
	CloseHandle(childInfo.hProcess);
	CloseHandle(childInfo.hThread);

	*child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY);
	*child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY);
	
	CloseHandle(childStdout[1]);
	CloseHandle(childStdin[0]);

	archive_string_free(&cmdline);
	archive_string_free(&fullpath);
	__archive_cmdline_free(acmd);
	return (childInfo.dwProcessId);

fail:
	if (childStdout[0] != INVALID_HANDLE_VALUE)
		CloseHandle(childStdout[0]);
	if (childStdout[1] != INVALID_HANDLE_VALUE)
		CloseHandle(childStdout[1]);
	if (childStdin[0] != INVALID_HANDLE_VALUE)
		CloseHandle(childStdin[0]);
	if (childStdin[1] != INVALID_HANDLE_VALUE)
		CloseHandle(childStdin[1]);
	if (childStderr != INVALID_HANDLE_VALUE)
		CloseHandle(childStderr);
	archive_string_free(&cmdline);
	archive_string_free(&fullpath);
	__archive_cmdline_free(acmd);
	return (-1);
}