Ejemplo n.º 1
0
Archivo: dir.cpp Proyecto: beanhome/dev
void DirTestCase::setUp()
{
    // create a test directory hierarchy
    wxDir::Make(DIRTEST_FOLDER + SEP + "folder1" + SEP + "subfolder1", wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
    wxDir::Make(DIRTEST_FOLDER + SEP + "folder1" + SEP + "subfolder2", wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
    wxDir::Make(DIRTEST_FOLDER + SEP + "folder2", wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
    wxDir::Make(DIRTEST_FOLDER + SEP + "folder3" + SEP + "subfolder1", wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
    
    CreateTempFile(DIRTEST_FOLDER + SEP + "folder1" + SEP + "subfolder2" + SEP + "dummy");
    CreateTempFile(DIRTEST_FOLDER + SEP + "dummy");
}
Ejemplo n.º 2
0
NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype)
{
    InstanceData *data = (InstanceData *)instance->pdata;

    if (!*data->exepath)
    {
        plogf("sp: NPP_NewStream() error: NPERR_FILE_NOT_FOUND");
        return NPERR_FILE_NOT_FOUND;
    }

    plogf("sp: NPP_NewStream() end=%d", stream->end);

    // if we can create a temporary file ourselfes, we manage the download
    // process. The reason for that is that NP_ASFILE (where browser manages
    // file downloading) is not reliable and has been broken in almost every
    // browser at some point

    *stype = NP_ASFILE;
    data->hFile = CreateTempFile(data->filepath, dimof(data->filepath));
    if (data->hFile)
    {
        plogf("sp: using temporary file: %S", data->filepath);
        *stype = NP_NORMAL;
    }

    data->totalSize = stream->end;
    data->currSize = 0;
    data->progress = stream->end > 0 ? 0.01f : 0;
    data->prevProgress = -.1f;
    TriggerRepaintOnProgressChange(data);
    
    return NPERR_NO_ERROR;
}
Ejemplo n.º 3
0
	LFA_FileRef FileInfo::Decompress()
	{

		if ( ! this->IsCompressed() ) return this->fileRef;
		
		LFA_FileRef updateRef = 0;
		std::string updatePath;

		try {

			CreateTempFile ( this->origFilePath, &updatePath, kCopyMacRsrc );
			updateRef = LFA_Open ( updatePath.c_str(), 'w' );
			this->tmpFilePath.assign ( updatePath );

			int ret = this->Encode ( this->fileRef, updateRef, FWS, Inf );
			this->tmpFileRef = updateRef;
			if ( ret != Z_OK ) XMP_Throw ( "zstream error occured", kXMPErr_ExternalFailure );

			return this->tmpFileRef;

		} catch ( ... ) {

			LFA_Close ( updateRef );
			LFA_Delete ( updatePath.c_str() );
			return this->fileRef;

		}

	}	// FileInfo::Decompress
Ejemplo n.º 4
0
SafeSaver::SafeSaver(const HUrl& inSpec)
	: fSavedFile(inSpec)
	, fTempFile(inSpec)
	, fCommited(false)
{
	int fd = CreateTempFile(inSpec.GetParent(), inSpec.GetFileName(), fTempFile);
	Close(fd);
}
Ejemplo n.º 5
0
bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile)
{
  if (!Remove())
    return false;
  if (!CreateTempFile(prefix, false, _path, outFile))
    return false;
  _mustBeDeleted = true;
  return true;
}
Ejemplo n.º 6
0
bool CTempDir::Create(CFSTR prefix)
{
  if (!Remove())
    return false;
  FString tempPath;
  if (!MyGetTempPath(tempPath))
    return false;
  if (!CreateTempFile(tempPath + prefix, true, _path, NULL))
    return false;
  _mustBeDeleted = true;
  return true;
}
Ejemplo n.º 7
0
bool CTempFile::CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFile)
{
  if (!Remove())
    return false;
  FString tempPath;
  if (!MyGetTempPath(tempPath))
    return false;
  if (!CreateTempFile(tempPath + namePrefix, true, _path, outFile))
    return false;
  _mustBeDeleted = true;
  return true;
}
Ejemplo n.º 8
0
XFILE::CFile *CXBMCTestUtils::CreateCorruptedFile(std::string const& strFileName,
  std::string const& suffix)
{
  XFILE::CFile inputfile, *tmpfile = CreateTempFile(suffix);
  unsigned char buf[20], tmpchar;
  unsigned int size, i;

  if (tmpfile && inputfile.Open(strFileName))
  {
    srand(time(NULL));
    while ((size = inputfile.Read(buf, sizeof(buf))) > 0)
    {
      for (i = 0; i < size; i++)
      {
        if ((rand() % RAND_MAX) < (probability * RAND_MAX))
        {
          tmpchar = buf[i];
          do
          {
            buf[i] = (rand() % 256);
          } while (buf[i] == tmpchar);
        }
      }
      if (tmpfile->Write(buf, size) < 0)
      {
        inputfile.Close();
        tmpfile->Close();
        DeleteTempFile(tmpfile);
        return NULL;
      }
    }
    inputfile.Close();
    tmpfile->Close();
    return tmpfile;
  }
  delete tmpfile;
  return NULL;
}
Ejemplo n.º 9
0
int
main()
{
    DWORD dwRead, dwWrite;
    char *cmdLine;
    HANDLE hStdInput, hStdOutput, hStdError;
    HANDLE hFileInput, hFileOutput, hFileError;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    char buf[8192];
    DWORD result;

    hFileInput = INVALID_HANDLE_VALUE;
    hFileOutput = INVALID_HANDLE_VALUE;
    hFileError = INVALID_HANDLE_VALUE;
    result = 1;

    /*
     * Don't get command line from argc, argv, because the command line
     * tokenizer will have stripped off all the escape sequences needed
     * for quotes and backslashes, and then we'd have to put them all
     * back in again.  Get the raw command line and parse off what we
     * want ourselves.  The command line should be of the form:
     *
     * stub16.exe program arg1 arg2 ...
     */

    cmdLine = strchr(GetCommandLine(), ' ');
    if (cmdLine == NULL) {
        return 1;
    }
    cmdLine++;

    hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    hStdError = GetStdHandle(STD_ERROR_HANDLE);

    if (GetFileType(hStdInput) == FILE_TYPE_PIPE) {
        hFileInput = CreateTempFile();
        if (hFileInput == INVALID_HANDLE_VALUE) {
            goto cleanup;
        }
        while (ReadFile(hStdInput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
            if (dwRead == 0) {
                break;
            }
            if (WriteFile(hFileInput, buf, dwRead, &dwWrite, NULL) == FALSE) {
                goto cleanup;
            }
        }
        SetFilePointer(hFileInput, 0, 0, FILE_BEGIN);
        SetStdHandle(STD_INPUT_HANDLE, hFileInput);
    }
    if (GetFileType(hStdOutput) == FILE_TYPE_PIPE) {
        hFileOutput = CreateTempFile();
        if (hFileOutput == INVALID_HANDLE_VALUE) {
            goto cleanup;
        }
        SetStdHandle(STD_OUTPUT_HANDLE, hFileOutput);
    }
    if (GetFileType(hStdError) == FILE_TYPE_PIPE) {
        hFileError = CreateTempFile();
        if (hFileError == INVALID_HANDLE_VALUE) {
            goto cleanup;
        }
        SetStdHandle(STD_ERROR_HANDLE, hFileError);
    }

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    if (CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si,
                      &pi) == FALSE) {
        goto cleanup;
    }

    WaitForInputIdle(pi.hProcess, 5000);
    WaitForSingleObject(pi.hProcess, INFINITE);
    GetExitCodeProcess(pi.hProcess, &result);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    if (hFileOutput != INVALID_HANDLE_VALUE) {
        SetFilePointer(hFileOutput, 0, 0, FILE_BEGIN);
        while (ReadFile(hFileOutput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
            if (dwRead == 0) {
                break;
            }
            if (WriteFile(hStdOutput, buf, dwRead, &dwWrite, NULL) == FALSE) {
                break;
            }
        }
    }
    if (hFileError != INVALID_HANDLE_VALUE) {
        SetFilePointer(hFileError, 0, 0, FILE_BEGIN);
        while (ReadFile(hFileError, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
            if (dwRead == 0) {
                break;
            }
            if (WriteFile(hStdError, buf, dwRead, &dwWrite, NULL) == FALSE) {
                break;
            }
        }
    }

cleanup:
    if (hFileInput != INVALID_HANDLE_VALUE) {
        CloseHandle(hFileInput);
    }
    if (hFileOutput != INVALID_HANDLE_VALUE) {
        CloseHandle(hFileOutput);
    }
    if (hFileError != INVALID_HANDLE_VALUE) {
        CloseHandle(hFileError);
    }
    CloseHandle(hStdInput);
    CloseHandle(hStdOutput);
    CloseHandle(hStdError);
    ExitProcess(result);
    return 1;
}
Ejemplo n.º 10
0
int G2A (int argc, char *argv[] )
{
	char origname[128];	// original name
	char newname [128];	// renumbered name
	char command [255];	// command buffer
	char *TempName;
	char *numstring;
	char ImageName[128];
	int  counter = 0;
	int  number;
	char *p;
	char nameFileName[255];
	char analyzeFileName[255];
	char headerFileName[255];
	char baseName[255];
	short verbose = true;
	FILE *nameFile;
	FILE *TempFile;
	FILE *dataFile;
	FILE *procFile;
	FILE *headerFile;
	FILE *inFile;
	int  i;
	IMAGE im;
	short count;
	short *dataBuff;
	Boolean DebugMode = false;
	
	static char id[] = "$Revision: 1.21 $$Date: 2006/06/09 18:40:34 $";
	OSErr error = noErr;

	if( argc < 2 ) {
		print_usage( argv[0] );
	}

// setup an output file name, based on the last input file name
	sprintf( baseName, "%s", argv[argc-1] );	// output file name

	p = strrchr( baseName, 'I' );
	*p = '\0';	// null terminate
	
	error = OpenProcFile( argc, argv, baseName, id, &procFile );
	ILError( error, "Opening Proc file" );
	
	sprintf( nameFileName, "%s.NAME_FILE", baseName );
	fprintf( procFile, "Associated name file ... %s\n", nameFileName );
	sprintf( headerFileName, "%s.GenesisHdrs", baseName );
	fprintf( procFile, "Associated headers file ... %s\n", headerFileName );

// corrected names will be stored temporarily in nameFile	
	error = CreateTempFile( &TempFile, &TempName );
	ILError( error, TempName );
	
// use UC_ReadHeader to determine image dimensions, etc...
	error = UC_Readheader( argv[argc-1], &im );
	if( error ) ILError( error, "Read Image" );

// rename the files and create name list into the file called TempName
   for( i=argc-1; i>0; i-- )
   {
		strcpy( origname, argv[i] );
		strcpy( newname, argv[i] );

		numstring = strrchr( newname, 'I' ) + 1;
		number = atoi( numstring );


		sprintf( numstring, "%0.3d.MR", number );

		fprintf( TempFile, "%s\n", newname );

		if( strcmp( origname, newname ) || DebugMode ) {
			if( verbose ) {
			    printf( "i:%d\t%s --> %s\n", i, origname, newname );
			}
		    sprintf( command, "mv %s %s\n", origname, newname );
		    fprintf( procFile, "\tRenamed %s to %s\n", origname, newname );
		    system( command );
		}
	}
	error = ck_fclose( TempFile );
	ILError( error, TempName );

// Sort the contents of the temporary nameFile and place it into the permanent version
	sprintf( command, "sort %s > %s", TempName, nameFileName );
	system( command );

	if( false ) {
		DBG( command );
		printf( "\nContents of name file\n" );
		sprintf( command, "cat %s", nameFileName );
		DBG( command );
		system( command );
	}
	
// now, place the name of the header file at the beginning of a file */
	error = CreateTempFile( &TempFile, &TempName );
	ILError ( error, TempName );

	fprintf( TempFile, "%s\n", headerFileName );
	error = ck_fclose( TempFile );
	ILError( error, TempName );
	
// add the file names to the end
	sprintf( command, "cat %s >> %s\n", nameFileName, TempName );
	system( command );
	
// and rename this file
	sprintf( command, "mv %s %s\n", TempName, nameFileName );
	system( command );
	
	if( false ) {
		printf( "new Contents of name file" );
		sprintf( command, "cat %s", nameFileName );
		DBG( command );
		system( command );
	}

	im.dim.n_slices = argc - 1;

	error = CreateHeader( ANALYZE, &im, baseName );
	if( error ) ILError( error, "Writing Header" );

	sprintf( analyzeFileName, "%s.img", baseName );
	error = ck_fopen( &dataFile, analyzeFileName, "wb" );
	ILError( error, "data file" );
	error = ck_fopen( &nameFile, nameFileName, "rb" );
	ILError( error, "name file" );
	error = ck_fopen( &headerFile, headerFileName, "wb" );
	ILError( error, "header file" );
	
	if( im.dim.x * im.dim.y * sizeof(short) < SIGHDRSIZE ) {
		dataBuff = (short *)ck_malloc( SIGHDRSIZE, "data buffer" );
	} else {
		dataBuff = (short *)ck_malloc( im.dim.x * im.dim.y * sizeof(short), "data buffer" );
	}
	
	count = fscanf( nameFile, "%s", headerFileName );	// just read past this.
	count = fscanf( nameFile, "%s", ImageName );

	if( false ) { DBG( ImageName ); }

	printf( "\n\tPatience for a moment\n" );

	while( count>0 ) {
		printf( "%d of %d complete\n", counter++, argc - 1 );
		error = ck_fopen( &inFile, ImageName, "rb" );
			ILError( error, "Opening image" );
		error = ck_fread ( dataBuff, sizeof( char ), SIGHDRSIZE, inFile );
			ILError( error, "Reading header" );
		error = ck_fwrite( dataBuff, sizeof( char ), SIGHDRSIZE, headerFile );
			ILError( error, "Writing image header" );
		error = ck_fread ( dataBuff, sizeof( short ), im.dim.x * im.dim.y, inFile );
			ILError( error, "Reading image data" );
		error = ck_fwrite( dataBuff, sizeof( short ), im.dim.x * im.dim.y, dataFile );
			ILError( error, "Writing image data" );
		ck_fclose( inFile );
		count = fscanf( nameFile, "%s", ImageName );
	}

	printf( "\n\nCreated Analyze (4D) file: %s\n", analyzeFileName );
	printf( "\tSave these files!: %s and %s\n\n", nameFileName, headerFileName );
	printf( "To create corresponding genesis images from an analyze file named XXX.img, use:\n" );
	printf( "\tAnalyze2Genesis -n %s -i XXX.img\n", nameFileName );

	free( dataBuff );	
	error = ck_fclose( headerFile );
		if( error ) ILError( error, headerFileName );
	error = ck_fclose( nameFile );
		if( error ) ILError( error, nameFileName );
	error = ck_fclose( dataFile );
		if( error ) ILError( error, analyzeFileName );
	error = ck_fclose( procFile );
		if( error ) ILError( error, "proc file" );

	return error;
}
Ejemplo n.º 11
0
HRESULT LoadAppDomain(ICorRuntimeHostPtr pHost, std::wstring addInFullPath, bool createSandboxedAppDomain, bool shadowCopyFiles, _AssemblyPtr& pLoaderAssembly , _AppDomainPtr& pAppDomain, bool& unloadAppDomain)
{
	HRESULT hr;
	std::wstring xllDirectory = addInFullPath;
	RemoveFileSpecFromPath(xllDirectory);
	unloadAppDomain = false;

	if (IsRunningOnCluster())
	{
		// Need to load into default AppDomain due to configuration issues of the cluster host.
		IUnknown *pAppDomainUnk = NULL;
		hr = pHost->CurrentDomain(&pAppDomainUnk);
		if (FAILED(hr) || pAppDomainUnk == NULL)
		{
			ShowMessage(IDS_MSG_HEADER_APPDOMAIN, 
						IDS_MSG_BODY_APPDOMAIN, 
						IDS_MSG_FOOTER_UNEXPECTED,
						hr);
		
			return E_FAIL;
		}
		// Assignment does QueryInterface
		pAppDomain = pAppDomainUnk;
		hr = LoadLoaderIntoAppDomain(pAppDomain, pLoaderAssembly, /*forceFromBytes=*/ true);
		if (FAILED(hr))
		{
			// Already showed error message there.
			return E_FAIL;
		}
		// Since we loaded into the default domain, don't unload the AppDomain later.
		unloadAppDomain = false;
		return S_OK;
	}
	// End of RunningOnCluster path.

	// Create and populate AppDomainSetup
	IUnknownPtr pAppDomainSetupUnk;
	hr = pHost->CreateDomainSetup(&pAppDomainSetupUnk);
	if (FAILED(hr) || pAppDomainSetupUnk == NULL)
	{
		ShowMessage(IDS_MSG_HEADER_APPDOMAIN, 
					IDS_MSG_BODY_APPDOMAINSETUP, 
					IDS_MSG_FOOTER_UNEXPECTED,
					hr);
		return E_FAIL;
	}

	IAppDomainSetupPtr pAppDomainSetup = pAppDomainSetupUnk;
	hr = pAppDomainSetup->put_ApplicationBase(_bstr_t(xllDirectory.c_str()));
	if (FAILED(hr))
	{
		ShowMessage(IDS_MSG_HEADER_APPDOMAIN, 
					IDS_MSG_BODY_APPLICATIONBASE, 
					IDS_MSG_FOOTER_UNEXPECTED,
					hr);
		return E_FAIL;
	}

	hr = pAppDomainSetup->put_ShadowCopyFiles(_bstr_t(shadowCopyFiles ? L"true" : L"false"));
	if (FAILED(hr))
	{
		ShowMessage(IDS_MSG_HEADER_APPDOMAIN, 
					IDS_MSG_BODY_SHADOWCOPYFILES, 
					IDS_MSG_FOOTER_UNEXPECTED,
					hr);
		return E_FAIL;
	}

	// AppDomainSetup.ApplicationName = "Excel-DNA: c:\MyAddins\MyAddIn.xll";
	_bstr_t appDomainName((std::wstring(L"Excel-DNA: ") + addInFullPath).c_str());
	pAppDomainSetup->put_ApplicationName(appDomainName);


	// Check if a .config file exists next to the .xll as MyAddIn.xll.config. Use it if it exists.
	std::wstring configFileName = addInFullPath + L".config";
	if (FileExists(configFileName.c_str()))
	{
		pAppDomainSetup->put_ConfigurationFile(_bstr_t(configFileName.c_str()));
	}
	else
	{
		// Try to load .config file from resources, store into a temp file
		HRSRC hResConfig = FindResource(hModuleCurrent, L"__MAIN__", L"CONFIG");
		if (hResConfig != NULL)
		{
			HGLOBAL hConfig = LoadResource(hModuleCurrent, hResConfig);
			void* pConfig = LockResource(hConfig);
			DWORD sizeConfig = SizeofResource(hModuleCurrent, hResConfig);

			std::wstring tempConfigFileName;
			hr = CreateTempFile(pConfig, sizeConfig, tempConfigFileName);
			if (SUCCEEDED(hr))
			{
				pAppDomainSetup->put_ConfigurationFile(_bstr_t(tempConfigFileName.c_str()));
			}
			// tempConfigFile will be deleted after the AppDomain has been unloaded.
		}
		else
		{
			// No config file - no problem.
		}
	}

	IUnknown *pAppDomainUnk = NULL;
	hr = pHost->CreateDomainEx(appDomainName, pAppDomainSetupUnk, 0, &pAppDomainUnk);
	if (FAILED(hr) || pAppDomainUnk == NULL)
	{
		ShowMessage(IDS_MSG_HEADER_APPDOMAIN, 
					IDS_MSG_BODY_APPDOMAIN, 
					IDS_MSG_FOOTER_UNEXPECTED,
					hr);
		return E_FAIL;
	}

	pAppDomain = pAppDomainUnk;

	hr = LoadLoaderIntoAppDomain(pAppDomain, pLoaderAssembly, /*forceLoadFromBytes=*/ false);
	if (FAILED(hr))
	{
		// Already showed message.
		return E_FAIL;
	}
	
	if (createSandboxedAppDomain)
	{
		_TypePtr pAppDomainHelperType;
		hr = pLoaderAssembly->GetType_2(_bstr_t(L"ExcelDna.Loader.AppDomainHelper"), &pAppDomainHelperType);
		if (FAILED(hr) || pAppDomainHelperType == NULL)
		{
			ShowMessage(IDS_MSG_HEADER_APPDOMAIN, 
						IDS_MSG_BODY_XLADDIN, 
						IDS_MSG_FOOTER_UNEXPECTED,
						hr);
			return E_FAIL;
		}

		_variant_t  sbRetVal;
		_variant_t  sbTarget;
		hr = pAppDomainHelperType->InvokeMember_3(_bstr_t("CreateFullTrustSandbox"), (BindingFlags)(BindingFlags_Static | BindingFlags_Public | BindingFlags_InvokeMethod), NULL, sbTarget, NULL, &sbRetVal);
		if (FAILED(hr))
		{
			ShowMessage(IDS_MSG_HEADER_APPDOMAIN, 
						IDS_MSG_BODY_XLADDININIT, 
						IDS_MSG_FOOTER_UNEXPECTED,
						hr);
			return E_FAIL;
		}

		_AppDomainPtr pSandbox(sbRetVal.punkVal);
		if (!IsEqualObject(pAppDomain, pSandbox))
		{
			// Unload the loader AppDomain.
			pLoaderAssembly.Release();
			pHost->UnloadDomain(pAppDomain);
			pAppDomain.Release();
			pAppDomain = pSandbox;

			//  Sort out the LoaderAssembly in the sandbox.
			hr = LoadLoaderIntoAppDomain(pAppDomain, pLoaderAssembly, /*forceLoadFromBytes=*/ false);
			if (FAILED(hr))
			{
				// Already showed message.
				return E_FAIL;
			}
		}
	}
	unloadAppDomain = true;
	return S_OK;
}
Ejemplo n.º 12
0
wchar_t* CConEmuUpdate::CreateBatchFile(LPCWSTR asPackage)
{
	BOOL lbRc = FALSE;
	HANDLE hBatch = NULL;
	wchar_t* pszBatch = NULL;
	wchar_t* pszCommand = NULL;
	BOOL lbWrite;
	DWORD nLen, nWritten;
	char szOem[4096];
	LPCWSTR pszFormat = NULL;
	size_t cchCmdMax = 0;

	wchar_t szPID[16]; _wsprintf(szPID, SKIPLEN(countof(szPID)) L"%u", GetCurrentProcessId());
	wchar_t szCPU[4]; wcscpy_c(szCPU, WIN3264TEST(L"x86",L"x64"));
	WARNING("Битность установщика? Если ставим в ProgramFiles64 на Win64");

	if (!gpConEmu)
	{
		ReportError(L"CreateBatchFile failed, gpConEmu==NULL", 0); goto wrap;
	}

	pszBatch = CreateTempFile(mp_Set->szUpdateDownloadPath, L"ConEmuUpdate.cmd", hBatch);
	if (!pszBatch)
		goto wrap;

	#define WRITE_BATCH_A(s) \
		nLen = lstrlenA(s); \
		lbWrite = WriteFile(hBatch, s, nLen, &nWritten, NULL); \
		if (!lbWrite || (nLen != nWritten)) { ReportError(L"WriteBatch failed, code=%u", GetLastError()); goto wrap; }

	#define WRITE_BATCH_W(s) \
		nLen = WideCharToMultiByte(CP_OEMCP, 0, s, -1, szOem, countof(szOem), NULL, NULL); \
		if (!nLen) { ReportError(L"WideCharToMultiByte failed, len=%i", lstrlen(s)); goto wrap; } \
		WRITE_BATCH_A(szOem);

	WRITE_BATCH_A("@echo off\r\n");

	// "set ConEmuInUpdate=YES"
	WRITE_BATCH_W(L"\r\nset " ENV_CONEMU_INUPDATE L"=" ENV_CONEMU_INUPDATE_YES L"\r\n");

	WRITE_BATCH_A("cd /d \"");
	WRITE_BATCH_W(gpConEmu->ms_ConEmuExeDir);
	WRITE_BATCH_A("\\\"\r\necho Current folder\r\ncd\r\necho .\r\n\r\necho Starting update...\r\n");

	// Формат.
	pszFormat = (mp_Set->UpdateDownloadSetup()==1) ? mp_Set->UpdateExeCmdLine() : mp_Set->UpdateArcCmdLine();

	// Замена %1 и т.п.
	for (int s = 0; s < 2; s++)
	{
		// На первом шаге - считаем требуемый размер под pszCommand, на втором - формируем команду
		if (s)
		{
			if (!cchCmdMax)
			{
				ReportError(L"Invalid %s update command (%s)", (mp_Set->UpdateDownloadSetup()==1) ? L"exe" : L"arc", pszFormat, 0);
				goto wrap;
			}
			pszCommand = (wchar_t*)malloc((cchCmdMax+1)*sizeof(wchar_t));
		}
		wchar_t* pDst = pszCommand;
		LPCWSTR pszMacro;
		for (LPCWSTR pSrc = pszFormat; *pSrc; pSrc++)
		{
			switch (*pSrc)
			{
			case L'%':
				pSrc++;
				switch (*pSrc)
				{
				case L'%':
					pszMacro = L"%";
					break;
				// "%1"-archive or setup file, "%2"-ConEmu.exe folder, "%3"-x86/x64, "%4"-ConEmu PID
				case L'1':
					pszMacro = asPackage;
					break;
				case L'2':
					pszMacro = gpConEmu->ms_ConEmuExeDir;
					break;
				case L'3':
					pszMacro = szCPU;
					break;
				case L'4':
					pszMacro = szPID;
					break;
				default:
					// Недопустимый управляющий символ, это может быть переменная окружения
					pszMacro = NULL;
					pSrc--;
					if (s)
						*(pDst++) = L'%';
					else
						cchCmdMax++;
				}

				if (pszMacro)
				{
					size_t cchLen = _tcslen(pszMacro);
					if (s)
					{
						_wcscpy_c(pDst, cchLen+1, pszMacro);
						pDst += cchLen;
					}
					else
					{
						cchCmdMax += cchLen;
					}
				}
				break;
			default:
				if (s)
					*(pDst++) = *pSrc;
				else
					cchCmdMax++;
			}
		}
		if (s)
			*pDst = 0;
	}

	// Выполнить команду обновления
	WRITE_BATCH_A("echo ");
	WRITE_BATCH_W(pszCommand);
	WRITE_BATCH_A("\r\ncall ");
	WRITE_BATCH_W(pszCommand);
	WRITE_BATCH_A("\r\nif errorlevel 1 goto err\r\n");

	// Если юзер просил что-то выполнить после распаковки установки	
	if (mp_Set->szUpdatePostUpdateCmd && *mp_Set->szUpdatePostUpdateCmd)
	{
		WRITE_BATCH_A("\r\n");
		WRITE_BATCH_W(mp_Set->szUpdatePostUpdateCmd);
		WRITE_BATCH_A("\r\n");
	}

	// Сброс переменной окружения: "set ConEmuInUpdate="
	WRITE_BATCH_W(L"\r\nset " ENV_CONEMU_INUPDATE L"=\r\n");

	// Перезапуск ConEmu
	WRITE_BATCH_A("\r\necho Starting ConEmu...\r\nstart \"ConEmu\" \"");
	WRITE_BATCH_W(gpConEmu->ms_ConEmuExe);
	WRITE_BATCH_A("\" ");
	if (bNeedRunElevation)
	{
		WRITE_BATCH_A("/demote /cmd \"");
		WRITE_BATCH_W(gpConEmu->ms_ConEmuExe);
		WRITE_BATCH_A("\" ");
	}
	if (gpConEmu->mpsz_ConEmuArgs)
	{
		WRITE_BATCH_W(gpConEmu->mpsz_ConEmuArgs);
	}
	// Fin
	WRITE_BATCH_A("\r\ngoto fin\r\n");

	// Сообщение об ошибке?
	WRITE_BATCH_A("\r\n:err\r\n");
	WRITE_BATCH_A((mp_Set->UpdateDownloadSetup()==1) ? "echo \7Installation failed\7" : "echo \7Extraction failed\7\r\n");
	WRITE_BATCH_A("\r\npause\r\n:fin\r\n");

	// Грохнуть пакет обновления
	if (!mp_Set->isUpdateLeavePackages)
	{
		WRITE_BATCH_A("del \"");
		WRITE_BATCH_W(asPackage);
		WRITE_BATCH_A("\"\r\n");
	}

	// Грохнуть сам батч и позвать "exit" чтобы в консоли
	// не появлялось "Batch not found" при попытке выполнить следующую строку файла
	WRITE_BATCH_A("del \"%~0\" & exit\r\n");

	//// Для отладки
	//WRITE_BATCH_A("\r\npause\r\n");

	// Succeeded
	lbRc = TRUE;
wrap:
	SafeFree(pszCommand);

	if (!lbRc)
	{
		SafeFree(pszBatch);
	}

	if (hBatch && hBatch != INVALID_HANDLE_VALUE)
	{
		CloseHandle(hBatch);
	}
	return pszBatch;
}
Ejemplo n.º 13
0
DWORD CConEmuUpdate::CheckProcInt()
{
	BOOL lbDownloadRc = FALSE, lbExecuteRc = FALSE;
	LPCWSTR pszUpdateVerLocationSet = mp_Set->UpdateVerLocation();
	wchar_t *pszUpdateVerLocation = NULL, *pszLocalPackage = NULL, *pszBatchFile = NULL;
	bool bTempUpdateVerLocation = false;
	wchar_t szSection[64], szItem[64];
	wchar_t szSourceFull[1024];
	wchar_t szTemplFilename[128];
	wchar_t *pszSource, *pszEnd, *pszFileName;
	DWORD nSrcLen, nSrcCRC, nLocalCRC = 0;
	bool lbSourceLocal;
	//INT_PTR nShellRc = 0;

#ifdef _DEBUG
	// Чтобы успел сервер проинититься и не ругался под отладчиком...
	if (!mb_ManualCallMode)
		Sleep(2500);
#endif

	_ASSERTE(m_UpdateStep==us_NotStarted);
	m_UpdateStep = us_Check;

	DeleteBadTempFiles();

	//120315 - OK, положим в архив и 64битный гуй
	//#ifdef _WIN64
	//if (mp_Set->UpdateDownloadSetup() == 2)
	//{
	//	if (mb_ManualCallMode)
	//	{
	//		ReportError(L"64bit versions of ConEmu may be updated with ConEmuSetup.exe only!", 0);
	//	}
	//	goto wrap;
	//}
	//#endif

	// This implies Inet.Deinit(false) too
	if (!Inet.Init(this))
	{
		goto wrap;
	}

	_wsprintf(ms_CurVersion, SKIPLEN(countof(ms_CurVersion)) L"%02u%02u%02u%s", (MVV_1%100),MVV_2,MVV_3,_T(MVV_4a));

	// Загрузить информацию о файлах обновления
	if (IsLocalFile(pszUpdateVerLocationSet))
	{
		pszUpdateVerLocation = (wchar_t*)pszUpdateVerLocationSet;
	}
	else
	{
		HANDLE hInfo = NULL;
		BOOL bInfoRc;
		DWORD crc;

		TODO("Было бы хорошо избавиться от *ini-файла* и парсить данные в памяти");
		pszUpdateVerLocation = CreateTempFile(mp_Set->szUpdateDownloadPath/*L"%TEMP%"*/, L"ConEmuVersion.ini", hInfo);
		if (!pszUpdateVerLocation)
			goto wrap;
		bTempUpdateVerLocation = true;

		bInfoRc = DownloadFile(pszUpdateVerLocationSet, pszUpdateVerLocation, hInfo, crc);
		CloseHandle(hInfo);
		if (!bInfoRc)
		{
			if (!mb_ManualCallMode)
			{
				DeleteFile(pszUpdateVerLocation);
				SafeFree(pszUpdateVerLocation);
			}
			goto wrap;
		}
	}

	// Проверить версии
	_wcscpy_c(szSection, countof(szSection),
		(mp_Set->isUpdateUseBuilds==1) ? sectionConEmuStable :
		(mp_Set->isUpdateUseBuilds==3) ? sectionConEmuPreview
		: sectionConEmuDevel);
	_wcscpy_c(szItem, countof(szItem), (mp_Set->UpdateDownloadSetup()==1) ? L"location_exe" : L"location_arc");

	if (!GetPrivateProfileString(szSection, L"version", L"", ms_NewVersion, countof(ms_NewVersion), pszUpdateVerLocation) || !*ms_NewVersion)
	{
		ReportBrokenIni(szSection, L"version", pszUpdateVerLocationSet);
		goto wrap;
	}

	// URL may not contain file name at all, compile it (predefined)
	_wsprintf(szTemplFilename, SKIPLEN(countof(szTemplFilename))
		(mp_Set->UpdateDownloadSetup()==1) ? L"ConEmuSetup.%s.exe" : L"ConEmuPack.%s.7z",
		ms_NewVersion);

	if (!GetPrivateProfileString(szSection, szItem, L"", szSourceFull, countof(szSourceFull), pszUpdateVerLocation) || !*szSourceFull)
	{
		ReportBrokenIni(szSection, szItem, pszUpdateVerLocationSet);
		goto wrap;
	}

	GetVersionsFromIni(pszUpdateVerLocation, ms_VerOnServer, ms_CurVerInfo);

	if ((lstrcmpi(ms_NewVersion, ms_CurVersion) <= 0)
		// Если пользователь отказался от обновления в этом сеансе - не предлагать ту же версию при ежечасных проверках
		|| (!mb_ManualCallMode && (lstrcmp(ms_NewVersion, ms_SkipVersion) == 0)))
	{
		// Новых версий нет
		if (mb_ManualCallMode)
		{
			wchar_t szFull[300];

			_wsprintf(szFull, SKIPLEN(countof(szFull)) 
				L"Your current ConEmu version is %s\n\n"
				L"Versions on server\n%s\n\n"
				L"No newer %s version is available",
				ms_CurVerInfo, ms_VerOnServer,
				(mp_Set->isUpdateUseBuilds==1) ? L"stable" : (mp_Set->isUpdateUseBuilds==3) ? L"preview" : L"developer", 0);
			ReportError(szFull, 0);
		}

		if (bTempUpdateVerLocation && pszUpdateVerLocation && *pszUpdateVerLocation)
		{
			DeleteFile(pszUpdateVerLocation);
			SafeFree(pszUpdateVerLocation);
		}
		goto wrap;
	}

	pszSource = szSourceFull;
	nSrcLen = wcstoul(pszSource, &pszEnd, 10);
	if (!nSrcLen || !pszEnd || *pszEnd != L',' || *(pszEnd+1) != L'x')
	{
		ReportError(L"Invalid format in version description (size)\n%s", szSourceFull, 0);
		goto wrap;
	}
	mn_PackageSize = nSrcLen;
	pszSource = pszEnd+2;
	nSrcCRC = wcstoul(pszSource, &pszEnd, 16);
	if (!nSrcCRC || !pszEnd || *pszEnd != L',')
	{
		ReportError(L"Invalid format in version description (CRC32)\n%s", szSourceFull, 0);
		goto wrap;
	}
	pszSource = pszEnd+1;
	lbSourceLocal = IsLocalFile(pszSource);

	if (mb_RequestTerminate)
		goto wrap;

	// It returns true, if updating with "exe" installer.
	if (!Check7zipInstalled())
		goto wrap; // Error already reported

	if (!QueryConfirmation(us_ConfirmDownload, pszSource))
	{
		// Если пользователь отказался от обновления в этом сеансе - не предлагать ту же версию при ежечасных проверках
		wcscpy_c(ms_SkipVersion, ms_NewVersion);
		goto wrap;
	}

	mn_InternetContentReady = 0;
	m_UpdateStep = us_Downloading;
	// May be null, if update package was dropped on ConEmu icon
	if (gpConEmu && ghWnd)
	{
		gpConEmu->UpdateProgress();
	}

	pszFileName = wcsrchr(pszSource, lbSourceLocal ? L'\\' : L'/');
	if (!pszFileName)
	{
		ReportError(L"Invalid source url\n%s", szSourceFull, 0);
		goto wrap;
	}
	else
	{
		// Загрузить пакет обновления
		pszFileName++; // пропустить слеш

		HANDLE hTarget = NULL;

		pszLocalPackage = CreateTempFile(mp_Set->szUpdateDownloadPath, szTemplFilename, hTarget);
		if (!pszLocalPackage)
			goto wrap;

		lbDownloadRc = DownloadFile(pszSource, pszLocalPackage, hTarget, nLocalCRC, TRUE);
		if (lbDownloadRc)
		{
			wchar_t szInfo[2048];
			LARGE_INTEGER liSize = {};
			if (!GetFileSizeEx(hTarget, &liSize) || liSize.HighPart || liSize.LowPart != nSrcLen)
			{
				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"%s\nRequired size=%u, local size=%u", pszSource, nSrcLen, liSize.LowPart);
				ReportError(L"Downloaded file does not match\n%s\n%s", pszLocalPackage, szInfo, 0);
				lbDownloadRc = FALSE;
			}
			else if (nLocalCRC != nSrcCRC)
			{
				_wsprintf(szInfo, SKIPLEN(countof(szInfo)) L"Required CRC32=x%08X, local CRC32=x%08X", nSrcCRC, nLocalCRC);
				ReportError(L"Invalid local file\n%s\n%s", pszLocalPackage, szInfo, 0);
				lbDownloadRc = FALSE;
			}
		}
		CloseHandle(hTarget);
		if (!lbDownloadRc)
			goto wrap;
	}

	Inet.Deinit(true);

	if (mb_RequestTerminate)
		goto wrap;

	pszBatchFile = CreateBatchFile(pszLocalPackage);
	if (!pszBatchFile)
		goto wrap;

	/*
	nShellRc = (INT_PTR)ShellExecute(ghWnd, bNeedRunElevation ? L"runas" : L"open", pszBatchFile, NULL, NULL, SW_SHOWMINIMIZED);
	if (nShellRc <= 32)
	{
		ReportError(L"Failed to start update batch\n%s\nError code=%i", pszBatchFile, (int)nShellRc);
		goto wrap;
	}
	*/
	if (!QueryConfirmation(us_ConfirmUpdate))
	{
		// Если пользователь отказался от обновления в этом сеансе - не предлагать ту же версию при ежечасных проверках
		wcscpy_c(ms_SkipVersion, ms_NewVersion);
		goto wrap;
	}
	mpsz_PendingPackageFile = pszLocalPackage;
	pszLocalPackage = NULL;
	mpsz_PendingBatchFile = pszBatchFile;
	pszBatchFile = NULL;
	m_UpdateStep = us_ExitAndUpdate;
	if (gpConEmu)
		gpConEmu->RequestExitUpdate();
	lbExecuteRc = TRUE;

wrap:
	_ASSERTE(mpsz_DeleteIniFile==NULL);
	mpsz_DeleteIniFile = NULL;
	if (bTempUpdateVerLocation && pszUpdateVerLocation)
	{
		if (*pszUpdateVerLocation)
			mpsz_DeleteIniFile = pszUpdateVerLocation;
			//DeleteFile(pszUpdateVerLocation);
		else
			SafeFree(pszUpdateVerLocation);
	}

	_ASSERTE(mpsz_DeletePackageFile==NULL);
	mpsz_DeletePackageFile = NULL;
	if (pszLocalPackage)
	{
		if (*pszLocalPackage && (!lbDownloadRc || (!lbExecuteRc && !mp_Set->isUpdateLeavePackages)))
			mpsz_DeletePackageFile = pszLocalPackage;
			//DeleteFile(pszLocalPackage);
		else
			SafeFree(pszLocalPackage);
	}

	_ASSERTE(mpsz_DeleteBatchFile==NULL);
	mpsz_DeleteBatchFile = NULL;
	if (pszBatchFile)
	{
		if (*pszBatchFile && !lbExecuteRc)
			mpsz_DeleteBatchFile = pszBatchFile;
			//DeleteFile(pszBatchFile);
		else
			SafeFree(pszBatchFile);
	}

	if (!lbExecuteRc)
		m_UpdateStep = us_NotStarted;

	Inet.Deinit(true);

	mb_InCheckProcedure = FALSE;
	return 0;
}
Ejemplo n.º 14
0
bool CConEmuUpdate::StartLocalUpdate(LPCWSTR asDownloadedPackage)
{
	bool bRc = false;
	LPCWSTR pszName, pszExt;
	HANDLE hTarget = NULL;
	wchar_t *pszLocalPackage = NULL, *pszBatchFile = NULL;
	DWORD nLocalCRC = 0;
	BOOL lbDownloadRc = FALSE, lbExecuteRc = FALSE;

	LPCWSTR pszPackPref = L"conemupack.";
	size_t lnPackPref = _tcslen(pszPackPref);
	LPCWSTR pszSetupPref = L"conemusetup.";
	size_t lnSetupPref = _tcslen(pszSetupPref);

	_ASSERTE(gpConEmu && gpConEmu->isMainThread());

	if (InUpdate() != us_NotStarted)
	{
		MBoxError(L"Checking for updates already started");
		goto wrap;
	}

	if (mb_InCheckProcedure)
	{
		Assert(mb_InCheckProcedure==FALSE);
		goto wrap;
	}

	DeleteBadTempFiles();
	Inet.Deinit(true);

	pszName = PointToName(asDownloadedPackage);
	pszExt = PointToExt(pszName);
	if (!pszName || !*pszName || !pszExt || !*pszExt)
	{
		AssertMsg(L"Invalid asDownloadedPackage");
		goto wrap;
	}

	// Запомнить текущие параметры обновления
	if (!mp_Set)
		mp_Set = new ConEmuUpdateSettings;
	mp_Set->LoadFrom(&gpSet->UpdSet);

	mb_ManualCallMode = TRUE;

	// Clear possible last error
	{
		MSectionLock SC; SC.Lock(mp_LastErrorSC, TRUE);
		SafeFree(ms_LastErrorInfo);
	}

	ms_NewVersion[0] = 0;

	if ((lstrcmpni(pszName, pszPackPref, lnPackPref) == 0)
		&& (lstrcmpi(pszExt, L".7z") == 0)
		&& (((pszExt - pszName) - lnPackPref + 1) < sizeof(ms_NewVersion)))
	{
		// Check it was NOT installed with "Setupper"
		if (mp_Set->UpdateDownloadSetup() == 1)
		{
			DontEnable de;
			LPCWSTR pszConfirm = L"ConEmu was installed with setup!\nAre you sure to update installation with 7zip?";
			int iBtn = MessageBox(NULL, pszConfirm, ms_DefaultTitle, MB_ICONEXCLAMATION|MB_SETFOREGROUND|MB_SYSTEMMODAL|MB_YESNO|MB_DEFBUTTON2);
			if (iBtn != IDYES)
			{
				goto wrap;
			}
		}

		if (!Check7zipInstalled())
			goto wrap; // Error already reported

		// Forcing usage of 7zip package!
		mp_Set->isUpdateDownloadSetup = 2;

		//if (!CanUpdateInstallation())
		//{
		//	// Значит 7zip обломается при попытке распаковки
		//	goto wrap;
		//}

		// OK
		size_t nLen = (pszExt - pszName) - lnPackPref;
		wmemmove(ms_NewVersion, pszName+lnPackPref, nLen);
		ms_NewVersion[nLen] = 0;
	}
	else if ((lstrcmpni(pszName, pszSetupPref, lnSetupPref) == 0)
		&& (lstrcmpi(pszExt, L".exe") == 0)
		&& (((pszExt - pszName) - lnSetupPref + 1) < sizeof(ms_NewVersion)))
	{
		// Must be installed with "Setupper"
		if (mp_Set->UpdateDownloadSetup() != 1)
		{
			MBoxError(L"ConEmu was not installed with setup! Can't update!");
			goto wrap;
		}

		// OK
		size_t nLen = (pszExt - pszName) - lnSetupPref;
		wmemmove(ms_NewVersion, pszName+lnSetupPref, nLen);
		ms_NewVersion[nLen] = 0;
	}
	else
	{
		AssertMsg(L"Invalid asDownloadedPackage (2)");
		goto wrap;
	}


	// Сразу проверим, как нужно будет запускаться
	bNeedRunElevation = NeedRunElevation();

	_wsprintf(ms_CurVersion, SKIPLEN(countof(ms_CurVersion)) L"%02u%02u%02u%s", (MVV_1%100),MVV_2,MVV_3,_T(MVV_4a));
	//ms_NewVersion

	// StartLocalUpdate - запуск обновления из локального пакета

	mb_InetMode = false;
	mb_DroppedMode = true;



	pszLocalPackage = CreateTempFile(mp_Set->szUpdateDownloadPath, PointToName(asDownloadedPackage), hTarget);
	if (!pszLocalPackage)
		goto wrap;

	lbDownloadRc = DownloadFile(asDownloadedPackage, pszLocalPackage, hTarget, nLocalCRC, TRUE);
	CloseHandle(hTarget);
	if (!lbDownloadRc)
		goto wrap;


	if (mb_RequestTerminate)
		goto wrap;

	pszBatchFile = CreateBatchFile(pszLocalPackage);
	if (!pszBatchFile)
		goto wrap;

	if (!QueryConfirmation(us_ConfirmUpdate))
	{
		goto wrap;
	}

	Assert(mb_ManualCallMode==TRUE);
	Assert(mpsz_PendingBatchFile==NULL);

	mpsz_PendingPackageFile = pszLocalPackage;
	pszLocalPackage = NULL;
	mpsz_PendingBatchFile = pszBatchFile;
	pszBatchFile = NULL;
	m_UpdateStep = us_ExitAndUpdate;
	if (gpConEmu)
		gpConEmu->RequestExitUpdate();
	lbExecuteRc = TRUE;

wrap:
	_ASSERTE(mpsz_DeleteIniFile==NULL);

	_ASSERTE(mpsz_DeletePackageFile==NULL);
	mpsz_DeletePackageFile = NULL;
	if (pszLocalPackage)
	{
		if (*pszLocalPackage && (!lbDownloadRc || (!lbExecuteRc && !mp_Set->isUpdateLeavePackages)))
			mpsz_DeletePackageFile = pszLocalPackage;
			//DeleteFile(pszLocalPackage);
		else
			SafeFree(pszLocalPackage);
	}

	_ASSERTE(mpsz_DeleteBatchFile==NULL);
	mpsz_DeleteBatchFile = NULL;
	if (pszBatchFile)
	{
		if (*pszBatchFile && !lbExecuteRc)
			mpsz_DeleteBatchFile = pszBatchFile;
			//DeleteFile(pszBatchFile);
		else
			SafeFree(pszBatchFile);
	}

	if (!lbExecuteRc)
	{
		m_UpdateStep = us_NotStarted;
		mb_DroppedMode = false;
	}

	return bRc;
}
Ejemplo n.º 15
0
CC_FILE_ERROR PhotoScanFilter::loadFile(const QString& filename,
										ccHObject& container,
										LoadParameters& parameters)
{
	QuaZip zip(filename);

	if (!zip.open(QuaZip::mdUnzip))
	{
		//failed to open or read the zip file
		return CC_FERR_READING;
	}

	QStringList fileList = zip.getFileNameList();
	if (fileList.isEmpty())
	{
		//empty archive?
		return CC_FERR_NO_LOAD;
	}

	static const QString s_defaultXMLFilename("doc.xml");

	if (!fileList.contains(s_defaultXMLFilename))
	{
		//empty archive?
		ccLog::Warning(QString("[Photoscan] Couldn't find '%1' in Photoscan archive").arg(s_defaultXMLFilename));
		return CC_FERR_NO_LOAD;
	}

	//look for the XML file
	if (!zip.setCurrentFile(s_defaultXMLFilename))
	{
		ccLog::Warning(QString("[Photoscan] Failed to locate '%1' in the Photoscan archive").arg(s_defaultXMLFilename));
		return CC_FERR_MALFORMED_FILE;
	}

	//decompress the XML file
	QuaZipFile zipXML(&zip);
	if (!zipXML.open(QFile::ReadOnly))
	{
		ccLog::Warning(QString("[Photoscan] Failed to extract '%1' from Photoscan archive").arg(s_defaultXMLFilename));
		return CC_FERR_NO_LOAD;
	}

	QXmlStreamReader stream(&zipXML);

	//expected: "document"
	if (!stream.readNextStartElement() || stream.name() != "document")
	{
		return CC_FERR_MALFORMED_FILE;
	}

	std::vector<Sections> sections;
	sections.push_back(DOCUMENT);

	QMap<int, ccCameraSensor*> sensors;
	QMap<int, CameraDesc> cameras;
	QList<CloudDesc> clouds;
	QList<MeshDesc> meshes;
	ccGLMatrixd globalTransform;
	bool hasGlobalTransform = false;

	while (true)
	{
		if (!stream.readNextStartElement())
		{
			//end of section?
			if (!sections.empty())
			{
				ccLog::PrintDebug(" < " + stream.name().toString() + QString(" [%1]").arg(ToName(sections.back())));
				sections.pop_back();
				//stream.skipCurrentElement();
				continue;
			}
			else
			{
				//end of file
				break;
			}
		}
		ccLog::PrintDebug(" > " + stream.name().toString());

		switch (sections.back())
		{
		case DOCUMENT:
			if (stream.name() == "chunks")
			{
				sections.push_back(CHUNKS);
			}
			else
			{
				//not handled
				stream.skipCurrentElement();
			}
			break;

		case CHUNKS:
			if (stream.name() == "chunk")
			{
				sections.push_back(CHUNK);
			}
			else
			{
				//not handled
				stream.skipCurrentElement();
			}
			break;

		case CHUNK:
			if (stream.name() == "sensors")
			{
				sections.push_back(SENSORS);
			}
			else if (stream.name() == "cameras")
			{
				sections.push_back(CAMERAS);
			}
			else if (stream.name() == "frames")
			{
				sections.push_back(FRAMES);
			}
			else if (stream.name() == "transform")
			{
				//inner loop
				while (stream.readNextStartElement())
				{
					if (stream.name() == "rotation")
					{
						QString rotationValues = stream.readElementText();
						if (DecodeRotation<double>(rotationValues, globalTransform))
						{
							hasGlobalTransform = true;
						}
						else
						{
							assert(false);
						}
					}
					stream.skipCurrentElement();
				}
			}
			else //frames, reference, region, settings, meta, etc.
			{
				//not handled for now
				stream.skipCurrentElement();
			}
			break;

		case SENSORS:
			if (stream.name() == "sensor")
			{
				int sensorId = -1;
				ccCameraSensor* sensor = DecodeSensor(stream, sensorId);
				if (sensor)
				{
					assert(!sensors.contains(sensorId));
					sensors.insert(sensorId, sensor);
					//currentContainer->addChild(sensor);
				}
			}
			else
			{
				//not handled
				stream.skipCurrentElement();
			}
			break;

		case CAMERAS:
			if (stream.name() == "camera")
			{
				CameraDesc camera;
				ccGLMatrix trans;
				if (DecodeCamera(stream, camera))
				{
					assert(!cameras.contains(camera.id));
					cameras.insert(camera.id, camera);
					//currentContainer->addChild(camera.image);
				}
			}
			else
			{
				//not handled
				stream.skipCurrentElement();
			}
			break;

		case FRAMES:
			if (stream.name() == "frame")
			{
				sections.push_back(FRAME);
			}
			else
			{
				//not handled
				stream.skipCurrentElement();
			}
			break;

		case FRAME:
			if (stream.name() == "point_cloud" || stream.name() == "dense_cloud")
			{
				//inner loop
				bool denseCloud = (stream.name() == "dense_cloud");
				while (stream.readNextStartElement())
				{
					if (stream.name() == "points")
					{
						if (stream.attributes().hasAttribute("path"))
						{
							CloudDesc desc;
							desc.filename = stream.attributes().value("path").toString();
							desc.type = (denseCloud ? "dense cloud" : "keypoints");
							clouds.push_back(desc);
						}
						else
						{
							assert(false);
						}
					}
					stream.skipCurrentElement();
				}
			}
			else if (stream.name() == "model")
			{
				MeshDesc desc;

				//inner loop
				while (stream.readNextStartElement())
				{
					if (stream.name() == "mesh")
					{
						if (stream.attributes().hasAttribute("path"))
						{
							desc.filename = stream.attributes().value("path").toString();
						}
						else
						{
							assert(false);
						}
					}
					else if (stream.name() == "texture")
					{
						if (stream.attributes().hasAttribute("path"))
						{
							desc.texture = stream.attributes().value("path").toString();
						}
						else
						{
							assert(false);
						}
					}
					stream.skipCurrentElement();
				}
				if (!desc.filename.isEmpty())
				{
					meshes.push_back(desc);
				}
			}
			else
			{
				//not handled
				stream.skipCurrentElement();
			}
			break;

		case TRANSFORM:
			//not handled
			stream.skipCurrentElement();
			break;

		default:
			break;
		}
	}

	QScopedPointer<ccProgressDialog> progressDialog(0);
	if (parameters.parentWidget)
	{
		progressDialog.reset(new ccProgressDialog(parameters.parentWidget));
		progressDialog->setRange(0, cameras.size() + clouds.size() + meshes.size());
		progressDialog->setWindowTitle("Loading data");
		progressDialog->start();
	}
	bool wasCanceled = false;
	int currentProgress = 0;

	//end of file: now we can sort the various extracted components
	QDir dir = QFileInfo(filename).dir();
	ccHObject* imageGroup = new ccHObject("Images");
	if (progressDialog && !cameras.empty())
	{
		progressDialog->setInfo(QString("Loading %1 image(s)").arg(cameras.size()));
	}
	for (CameraDesc& camera : cameras)
	{
		//progress
		if (progressDialog)
		{
			progressDialog->setValue(++currentProgress);
			if (progressDialog->wasCanceled())
			{
				wasCanceled = true;
				break;
			}
		}
		if (camera.imageFilename.isEmpty())
		{
			assert(false);
			continue;
		}

		//DGM: the images are not in the archive!
		//if (!zip.setCurrentFile(camera.imageFilename))
		//{
		//	ccLog::Warning(QString("[Photoscan] Failed to locate image '%1' in the Photoscan archive").arg(camera.imageFilename));
		//	continue;
		//}

		////decompress the image file
		//QuaZipFile zipImage(&zip);
		//if (!zipImage.open(QFile::ReadOnly))
		//{
		//	ccLog::Warning(QString("[Photoscan] Failed to extract '%1' from Photoscan archive").arg(camera.imageFilename));
		//	continue;
		//}

		QImage qImage;
		QString absoluteImageFilename = dir.absoluteFilePath(camera.imageFilename);
		//if (!qImage.load(&zipImage, qPrintable(QFileInfo(camera.imageFilename).suffix())))
		if (!qImage.load(absoluteImageFilename))
		{
			ccLog::Warning(QString("[Photoscan] Failed to load image '%1'").arg(camera.imageFilename));
			continue;
		}

		ccCameraSensor* const origSensor = sensors[camera.sensorId];
		if (origSensor)
		{
			origSensor->undistort(qImage);
		}

		ccImage* image = new ccImage(qImage);
		image->setName(camera.imageFilename);
		image->setAlpha(0.5f);
		image->setVisible(false);

		//associated sensor (if any)
		if (origSensor)
		{
			//make a copy of the original sensor
			ccCameraSensor* sensor = new ccCameraSensor(*origSensor);

			camera.trans.setColumn(1, -camera.trans.getColumnAsVec3D(1));
			camera.trans.setColumn(2, -camera.trans.getColumnAsVec3D(2));

			//FIXME: we would have to transform the clouds and meshes as well!
			//if (hasGlobalTransform)
			//{
			//	//apply global transformation (if any)
			//	camera.trans = ccGLMatrix(globalTransform.data()) * camera.trans;
			//}
			sensor->setRigidTransformation(camera.trans);
			sensor->setVisible(true);
			sensor->setGraphicScale(0.1f);
			image->setAssociatedSensor(sensor);
			image->addChild(sensor);
			imageGroup->addChild(image);
		}
	}
	if (imageGroup->getChildrenNumber())
	{
		container.addChild(imageGroup);
	}
	else
	{
		//no image?!
		delete imageGroup;
		imageGroup = 0;
	}

	//we can get rid of the original sensors
	for (ccCameraSensor*& sensor : sensors)
	{
		delete sensor;
		sensor = 0;
	}
	sensors.clear();

	//clouds
	if (!wasCanceled)
	{
		if (progressDialog && !clouds.empty())
		{
			progressDialog->setInfo(QString("Loading %1 cloud(s)").arg(cameras.size()));
		}
		for (CloudDesc& desc : clouds)
		{
			//progress
			if (progressDialog)
			{
				progressDialog->setValue(++currentProgress);
				if (progressDialog->wasCanceled())
				{
					wasCanceled = true;
					break;
				}
			}

			if (desc.filename.isEmpty())
			{
				assert(false);
				continue;
			}

			if (desc.filename.endsWith(".oc3", Qt::CaseInsensitive))
			{
				ccLog::Warning(QString("[Photoscan] OC3 format not supported. Can't import %1 from the Photoscan archive").arg(desc.type));
				continue;
			}

			QString tempFilename = CreateTempFile(zip, desc.filename);
			if (tempFilename.isNull())
			{
				continue;
			}

			ccHObject tempContainer;
			FileIOFilter::LoadParameters params;
			params.alwaysDisplayLoadDialog = false;
			params.autoComputeNormals = false;
			params.parentWidget = 0;
			CC_FILE_ERROR result = CC_FERR_NO_ERROR;
			ccHObject* newGroup = FileIOFilter::LoadFromFile(tempFilename, params, result);
			if (newGroup)
			{
				newGroup->setName(desc.type);
				if (desc.type == "keypoints")
				{
					newGroup->setEnabled(false);
				}
				container.addChild(newGroup);
			}
			else
			{
				ccLog::Warning(QString("[Photoscan] Failed to extract '%1' from Photoscan archive").arg(desc.filename));
			}
			QFile::remove(tempFilename);
		}
	}

	//meshes
	if (!wasCanceled)
	{
		if (progressDialog && !meshes.empty())
		{
			progressDialog->setInfo(QString("Loading %1 mesh(es)").arg(cameras.size()));
		}
		for (MeshDesc& desc : meshes)
		{
			//progress
			if (progressDialog)
			{
				progressDialog->setValue(++currentProgress);
				if (progressDialog->wasCanceled())
				{
					wasCanceled = true;
					break;
				}
			}

			if (desc.filename.isEmpty())
			{
				assert(false);
				continue;
			}

			QString tempFilename = CreateTempFile(zip, desc.filename);
			if (tempFilename.isNull())
			{
				continue;
			}

			FileIOFilter::LoadParameters params;
			params.alwaysDisplayLoadDialog = false;
			params.autoComputeNormals = false;
			params.parentWidget = 0;

			bool success = false;
			if (!desc.texture.isEmpty() && desc.filename.endsWith("ply", Qt::CaseInsensitive))
			{
				QString tempTextureFilename = CreateTempFile(zip, desc.texture);

				ccHObject tempContainer;
				if (PlyFilter().loadFile(tempFilename, desc.texture, tempContainer, params) == CC_FERR_NO_ERROR)
				{
					success = true;
					//transfer the loaded entities to the current container
					for (unsigned i = 0; i < tempContainer.getChildrenNumber(); ++i)
					{
						container.addChild(tempContainer.getChild(i));
					}
					tempContainer.detatchAllChildren();
				}

				if (!tempTextureFilename.isNull())
				{
					QFile::remove(tempTextureFilename);
				}
			}
			else
			{
				CC_FILE_ERROR result = CC_FERR_NO_ERROR;
				ccHObject* newGroup = FileIOFilter::LoadFromFile(tempFilename, params, result);
				if (newGroup)
				{
					success = true;
					//transfer the loaded entities to the current container
					for (unsigned i = 0; i < newGroup->getChildrenNumber(); ++i)
					{
						container.addChild(newGroup->getChild(i));
					}
					newGroup->detatchAllChildren();
					delete newGroup;
					newGroup = 0;
				}
			}

			if (!success)
			{
				ccLog::Warning(QString("[Photoscan] Failed to extract '%1' from Photoscan archive").arg(desc.filename));
			}

			QFile::remove(tempFilename);
		}
	}

	if (progressDialog)
	{
		progressDialog->stop();
	}

	return wasCanceled ? CC_FERR_CANCELED_BY_USER : CC_FERR_NO_ERROR;
}
Ejemplo n.º 16
0
/*
 *---------------------------------------------------------------------------
 *
 * Blt_CreatePipeline --
 *
 *	Given an objc/objv array, instantiate a pipeline of processes as
 *	described by the objv.
 *
 * Results:
 *	The return value is a count of the number of new processes created, or
 *	-1 if an error occurred while creating the pipeline.  *pidArrayPtr is
 *	filled in with the address of a dynamically allocated array giving the
 *	ids of all of the processes.
 *
 *	It is up to the caller to free this array when it isn't needed
 *	anymore.
 *
 *	If stdinPipePtr isn't NULL, then *stdinPipePtr is filled with the file
 *	id for the input pipe for the pipeline (if any): the caller must
 *	eventually close this file.
 *
 *	If stdoutPipePtr isn't NULL, then *stdoutPipePtr is filled with the
 *	file id for the output pipe from the pipeline: the caller must close
 *	this file.
 *
 *	If stderrPipePtr isn't NULL, then *stderrPipePtr is filled with a file
 *	id that may be used to read error output after the pipeline completes.
 *
 * Side effects:
 *	Processes and pipes are created.
 *
 *---------------------------------------------------------------------------
 */
int
Blt_CreatePipeline(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    int objc,			/* Number of entries in objv. */
    Tcl_Obj *const *objv,	/* Array of strings describing commands in
				 * pipeline plus I/O redirection with <, <<,
				 * >, etc.  Objv[objc] must be NULL. */
    ProcessId **pidArrayPtr,	/* (out) Word at *pidArrayPtr gets filled in
				 * with address of array of pids for processes
				 * in pipeline (first pid is first process in
				 * pipeline). */
    int *stdinPipePtr,		/* (out) If non-NULL, input to the pipeline
				 * comes from a pipe (unless overridden by
				 * redirection in the command).  The file id
				 * with which to write to this pipe is stored
				 * at *stdinPipePtr.  NULL means command
				 * specified its own input source. */
    int *stdoutPipePtr,		/* (out) If non-NULL, output to the pipeline
				 * goes to a pipe, unless overriden by
				 * redirection in the command.  The file id
				 * with which to read frome this pipe is
				 * stored at *stdoutPipePtr.  NULL means
				 * command specified its own output sink. */
    int *stderrPipePtr)		/* (out) If non-NULL, all stderr output from
				 * the pipeline will go to a temporary file
				 * created here, and a descriptor to read the
				 * file will be left at *stderrPipePtr.  The
				 * file will be removed already, so closing
				 * this descriptor will be the end of the
				 * file.  If this is NULL, then all stderr
				 * output goes to our stderr.  If the pipeline
				 * specifies redirection then the file will
				 * still be created but it will never get any
				 * data. */
{
    int *pids = NULL;		/* Points to malloc-ed array holding all the
				 * pids of child processes. */
    int nPids;			/* Actual number of processes that exist at
				 * *pids right now. */
    int cmdCount;		/* Count of number of distinct commands found
				 * in objc/objv. */
    char *inputLiteral = NULL;	/* If non-null, then this points to a string
				 * containing input data (specified via <<) to
				 * be piped to the first process in the
				 * pipeline. */
    char *p;
    int skip, lastBar, lastArg, i, j, atOK, flags, errorToOutput;
    Tcl_DString execBuffer;
    int pipeIn;
    int isOpen[3];
    int curFd[3];		/* If non-zero, then fd should be closed
    				 * when cleaning up. */
    int fd[3];
    
    char **argv;

    fd[0] = fd[1] = fd[2] = -1;
    isOpen[0] = isOpen[1] = isOpen[2] = FALSE;
    if (stdinPipePtr != NULL) {
	*stdinPipePtr = -1;
    }
    if (stdoutPipePtr != NULL) {
	*stdoutPipePtr = -1;
    }
    if (stderrPipePtr != NULL) {
	*stderrPipePtr = -1;
    }
    Tcl_DStringInit(&execBuffer);

    pipeIn = curFd[0] = curFd[1] = -1;
    nPids = 0;

    /*
     * First, scan through all the arguments to figure out the structure of
     * the pipeline.  Process all of the input and output redirection
     * arguments and remove them from the argument list in the pipeline.
     * Count the number of distinct processes (it's the number of "|"
     * arguments plus one) but don't remove the "|" arguments because they'll
     * be used in the second pass to seperate the individual child processes.
     *
     * Cannot start the child processes in this pass because the redirection
     * symbols may appear anywhere in the command line -- e.g., the '<' that
     * specifies the input to the entire pipe may appear at the very end of
     * the argument list.
     */

    /* Convert all the Tcl_Objs to strings. */
    argv = Blt_AssertMalloc((objc + 1) *  sizeof(char *));
    for (i = 0; i < objc; i++) {
	argv[i] = Tcl_GetString(objv[i]);
    }
    argv[i] = NULL;

    lastBar = -1;
    cmdCount = 1;
    for (i = 0; i < objc; i++) {
	skip = 0;
	p = argv[i];
	switch (*p++) {
	case '\\':
	    p++;
	    continue;

	case '|':
	    if (*p == '&') {
		p++;
	    }
	    if (*p == '\0') {
		if ((i == (lastBar + 1)) || (i == (objc - 1))) {
		    Tcl_AppendResult(interp, 
			"illegal use of | or |& in command", (char *)NULL);
		    goto error;
		}
	    }
	    lastBar = i;
	    cmdCount++;
	    break;

	case '<':
	    if (isOpen[0] != 0) {
		isOpen[0] = FALSE;
		CloseFile(fd[0]);
	    }
	    if (*p == '<') {
		fd[0] = -1;
		inputLiteral = p + 1;
		skip = 1;
		if (*inputLiteral == '\0') {
		    inputLiteral = argv[i + 1];
		    if (inputLiteral == NULL) {
			Tcl_AppendResult(interp, "can't specify \"", argv[i], 
				"\" as last word in command", (char *)NULL);
			goto error;
		    }
		    skip = 2;
		}
	    } else {
		inputLiteral = NULL;
		fd[0] = FileForRedirect(interp, p, argv[i], TRUE, argv[i + 1],
			O_RDONLY, &skip, &isOpen[0]);
		if (fd[0] < 0) {
		    goto error;
		}
	    }
	    break;

	case '>':
	    atOK = TRUE;
	    flags = O_WRONLY | O_CREAT | O_TRUNC;
	    errorToOutput = FALSE;
	    if (*p == '>') {
		p++;
		atOK = FALSE;
		flags = O_WRONLY | O_CREAT;
	    }
	    if (*p == '&') {
		if (isOpen[2] != 0) {
		    isOpen[2] = FALSE;
		    CloseFile(fd[2]);
		}
		errorToOutput = TRUE;
		p++;
	    }
	    if (isOpen[1] != 0) {
		isOpen[1] = FALSE;
		CloseFile(fd[1]);
	    }
	    fd[1] = FileForRedirect(interp, p, argv[i], atOK, argv[i + 1], 
		flags, &skip, &isOpen[1]);
	    if (fd[1] < 0) {
		goto error;
	    }
	    if (errorToOutput) {
		isOpen[2] = FALSE;
		fd[2] = fd[1];
	    }
	    break;

	case '2':
	    if (*p != '>') {
		break;
	    }
	    p++;
	    atOK = TRUE;
	    flags = O_WRONLY | O_CREAT | O_TRUNC;
	    if (*p == '>') {
		p++;
		atOK = FALSE;
		flags = O_WRONLY | O_CREAT;
	    }
	    if (isOpen[2] != 0) {
		isOpen[2] = FALSE;
		CloseFile(fd[2]);
	    }
	    fd[2] = FileForRedirect(interp, p, argv[i], atOK, argv[i + 1], 
		flags, &skip, &isOpen[2]);
	    if (fd[2] < 0) {
		goto error;
	    }
	    break;
	}

	if (skip != 0) {
	    for (j = i + skip; j < objc; j++) {
		argv[j - skip] = argv[j];
	    }
	    objc -= skip;
	    i -= 1;
	}
    }

    if (fd[0] == -1) {
	if (inputLiteral != NULL) {
	    /*
	     * The input for the first process is immediate data coming from
	     * Tcl.  Create a temporary file for it and put the data into the
	     * file.
	     */
	    fd[0] = CreateTempFile(inputLiteral);
	    if (fd[0] < 0) {
		Tcl_AppendResult(interp,
		    "can't create input file for command: ",
		    Tcl_PosixError(interp), (char *)NULL);
		goto error;
	    }
	    isOpen[0] = TRUE;
	} else if (stdinPipePtr != NULL) {
	    /*
	     * The input for the first process in the pipeline is to come from
	     * a pipe that can be written from by the caller.
	     */
	    if (CreatePipe(interp, &fd[0], stdinPipePtr) != TCL_OK) {
		goto error;
	    }
	    isOpen[0] = TRUE;
	} else {
	    /*
	     * The input for the first process comes from stdin.
	     */
	    fd[0] = 0;
	}
    }
    if (fd[1] == -1) {
	if (stdoutPipePtr != NULL) {
	    /*
	     * Output from the last process in the pipeline is to go to a pipe
	     * that can be read by the caller.
	     */
	    if (CreatePipe(interp, stdoutPipePtr, &fd[1]) != TCL_OK) {
		goto error;
	    }
	    isOpen[1] = TRUE;
	} else {
	    /*
	     * The output for the last process goes to stdout.
	     */
	    fd[1] = 1;
	}
    }
    if (fd[2] == -1) {
	if (stderrPipePtr != NULL) {
	    /*
	     * Stderr from the last process in the pipeline is to go to a pipe
	     * that can be read by the caller.
	     */
	    if (CreatePipe(interp, stderrPipePtr, &fd[2]) != TCL_OK) {
		goto error;
	    }
	    isOpen[2] = TRUE;
	} else {
	    /*
	     * Errors from the pipeline go to stderr.
	     */
	    fd[2] = 2;
	}
    }
    /*
     * Scan through the objc array, creating a process for each group of
     * arguments between the "|" characters.
     */

    Tcl_ReapDetachedProcs();
    pids = Blt_AssertMalloc(cmdCount * sizeof(int));
    curFd[0] = fd[0];

    lastArg = 0;		/* Suppress compiler warning */
    for (i = 0; i < objc; i = lastArg + 1) {
	int joinThisError;
	int pid;

	/*
	 * Convert the program name into native form.
	 */

	argv[i] = Tcl_TranslateFileName(interp, argv[i], &execBuffer);
	if (argv[i] == NULL) {
	    goto error;
	}
	/*
	 * Find the end of the curent segment of the pipeline.
	 */
	joinThisError = 0;
	for (lastArg = i + 1; lastArg < objc; lastArg++) {
	    if (argv[lastArg][0] == '|') {
		if (argv[lastArg][1] == '\0') {
		    break;
		}
		if ((argv[lastArg][1] == '&') && (argv[lastArg][2] == '\0')) {
		    joinThisError = 1;
		    break;
		}
	    }
	}
	argv[lastArg] = NULL;

	/*
	 * If this is the last segment, use the specified fd[1].  Otherwise
	 * create an intermediate pipe.  pipeIn will become the curInFile for
	 * the next segment of the pipe.
	 */
	if (lastArg == objc) {
	    curFd[1] = fd[1];
	} else {
	    if (CreatePipe(interp, &pipeIn, &curFd[1]) != TCL_OK) {
		goto error;
	    }
	}

	if (joinThisError != 0) {
	    curFd[2] = curFd[1];
	} else {
	    curFd[2] = fd[2];
	}

	if (CreateProcess(interp, lastArg - i, argv + i, curFd[0], curFd[1], 
		curFd[2], &pid) != TCL_OK) {
	    goto error;
	}
	Tcl_DStringFree(&execBuffer);

	pids[nPids] = pid;
	nPids++;

	/*
	 * Close off our copies of file descriptors that were set up for this
	 * child, then set up the input for the next child.
	 */
	if ((curFd[0] >= 0) && (curFd[0] != fd[0])) {
	    CloseFile(curFd[0]);
	}
	curFd[0] = pipeIn;
	pipeIn = -1;

	if ((curFd[1] >= 0) && (curFd[1] != fd[1])) {
	    CloseFile(curFd[1]);
	}
	curFd[1] = -1;
    }

    *pidArrayPtr = pids;

    /*
     * All done.  Cleanup open files lying around and then return.
     */

  cleanup:
    Tcl_DStringFree(&execBuffer);

    for (i = 0; i < 3; i++) {
	if (isOpen[i]) {
	    CloseFile(fd[i]);
	}
    }
    if (argv != NULL) {
	Blt_Free(argv);
    }
    return nPids;

    /*
     * An error occured.  There could have been extra files open, such as
     * pipes between children.  Clean them all up.  Detach any child processes
     * that have been created.
     */

  error:
    if (pipeIn >= 0) {
	CloseFile(pipeIn);
    }
    if ((curFd[2] >= 0) && (curFd[2] != fd[2])) {
	CloseFile(curFd[2]);
    }
    if ((curFd[1] >= 0) && (curFd[1] != fd[1])) {
	CloseFile(curFd[1]);
    }
    if ((curFd[0] >= 0) && (curFd[0] != fd[0])) {
	CloseFile(curFd[0]);
    }
    if ((stdinPipePtr != NULL) && (*stdinPipePtr >= 0)) {
	CloseFile(*stdinPipePtr);
	*stdinPipePtr = -1;
    }
    if ((stdoutPipePtr != NULL) && (*stdoutPipePtr >= 0)) {
	CloseFile(*stdoutPipePtr);
	*stdoutPipePtr = -1;
    }
    if ((stderrPipePtr != NULL) && (*stderrPipePtr >= 0)) {
	CloseFile(*stderrPipePtr);
	*stderrPipePtr = -1;
    }
    if (pids != NULL) {
	for (i = 0; i < nPids; i++) {
	    if (pids[i] != -1) {
		Tcl_DetachPids(1, (Tcl_Pid *)(pids + i));
	    }
	}
	Blt_Free(pids);
    }
    nPids = -1;
    goto cleanup;
}