void TestRegUtils::TestRecurseDeleteKey() { CStdString sRegEditPath = SystemFolderInfo::GetWindowsPath() + _T("\\regedit.exe"); CStdString sArgs = _T("/s \"") + CTestUtils::GetTestFileFolder() + _T("TestRegUtils\\TestMigrateSettingsCleanUP.reg\""); _tspawnlp( _P_WAIT, sRegEditPath.c_str(), sRegEditPath .c_str(), sArgs.c_str(), NULL ); assertTest(RegUtils::IsRegKeyPresent(HKEY_CURRENT_USER, _T("Software\\DeltaView Migration Tests\\TestMigrateSettingsCleanUp"))); assertTest(RegUtils::RecursiveDeleteKey(HKEY_CURRENT_USER, _T("Software\\DeltaView Migration Tests"))); assertTest(!RegUtils::IsRegKeyPresent(HKEY_CURRENT_USER, _T("Software\\DeltaView Migration Tests"))); }
static void CallPatchEntry() { auto output_file = FindOutputFile(); if (!output_file.empty()) { // FIXME: requires PatchEntry.exe in path auto errnum = _tspawnlp(_P_WAIT, TEXT("PatchEntry"), TEXT("PatchEntry"), output_file.c_str(), NULL); if (errnum) { perror("LinkWrapper:PatchEntry"); fprintf(stderr, "PatchEntry return value:%d\n", errnum); exit(errnum); } } }
FILE * __cdecl _tpopen ( const _TSCHAR *cmdstring, const _TSCHAR *type ) { int phdls[2]; /* I/O handles for pipe */ int ph_open[2]; /* flags, set if correspond phdls is open */ int i1; /* index into phdls[] */ int i2; /* index into phdls[] */ int tm = 0; /* flag indicating text or binary mode */ int stdhdl; /* either STDIN or STDOUT */ HANDLE osfhndsv1; /* used to save _osfhnd(stdhdl) */ long osfhndsv2; /* used to save _osfhnd(phdls[i2]) */ char osfilesv1; /* used to save _osfile(stdhdl) */ char osfilesv2; /* used to save _osfile(phdls[i2]) */ HANDLE oldhnd; /* used to hold OS file handle values... */ HANDLE newhnd; /* ...in calls to DuplicateHandle API */ FILE *pstream; /* stream to be associated with pipe */ HANDLE prochnd; /* handle for current process */ _TSCHAR *cmdexe; /* pathname for the command processor */ int childhnd; /* handle for child process (cmd.exe) */ IDpair *locidpair; /* pointer to IDpair table entry */ /* first check for errors in the arguments */ if ( (cmdstring == NULL) || (type == NULL) || ((*type != 'w') && (*type != _T('r'))) ) goto error1; /* do the _pipe(). note that neither of the resulting handles will * be inheritable. */ if ( *(type + 1) == _T('t') ) tm = _O_TEXT; else if ( *(type + 1) == _T('b') ) tm = _O_BINARY; tm |= _O_NOINHERIT; if ( _pipe( phdls, PSIZE, tm ) == -1 ) goto error1; /* test *type and set stdhdl, i1 and i2 accordingly. */ if ( *type == _T('w') ) { stdhdl = STDIN; i1 = 0; i2 = 1; } else { stdhdl = STDOUT; i1 = 1; i2 = 0; } /* the pipe now exists. the following steps must be carried out before * the child process (cmd.exe) may be spawned: * * 1. save a non-inheritable dup of stdhdl * * 2. force stdhdl to be a dup of ph[i1]. close both ph[i1] and * the original OS handle underlying stdhdl * * 3. associate a stdio-level stream with ph[i2]. */ /* set flags to indicate pipe handles are open. note, these are only * used for error recovery. */ ph_open[ 0 ] = ph_open[ 1 ] = 1; /* get the process handle, it will be needed in some API calls */ prochnd = GetCurrentProcess(); /* MULTI-THREAD: ASSERT LOCK ON STDHDL HERE!!!! */ _lock_fh( stdhdl ); /* save a non-inheritable copy of stdhdl for later restoration. */ oldhnd = (HANDLE)_osfhnd( stdhdl ); if ( (oldhnd == INVALID_HANDLE_VALUE) || !DuplicateHandle( prochnd, oldhnd, prochnd, &osfhndsv1, 0L, FALSE, /* non-inheritable */ DUPLICATE_SAME_ACCESS ) ) { goto error2; } osfilesv1 = _osfile( stdhdl ); /* force stdhdl to an inheritable dup of phdls[i1] (i.e., force * STDIN to the pipe read handle or STDOUT to the pipe write handle) * and close phdls[i1] (so there won't be a stray open handle on the * pipe after a _pclose). also, clear ph_open[i1] flag so that error * recovery won't try to close it again. */ if ( !DuplicateHandle( prochnd, (HANDLE)_osfhnd( phdls[i1] ), prochnd, &newhnd, 0L, TRUE, /* inheritable */ DUPLICATE_SAME_ACCESS ) ) { goto error3; } (void)CloseHandle( (HANDLE)_osfhnd(stdhdl) ); _free_osfhnd( stdhdl ); _set_osfhnd( stdhdl, (long)newhnd ); _osfile( stdhdl ) = _osfile( phdls[i1] ); (void)_close( phdls[i1] ); ph_open[ i1 ] = 0; /* associate a stream with phdls[i2]. note that if there are no * errors, pstream is the return value to the caller. */ if ( (pstream = _tfdopen( phdls[i2], type )) == NULL ) goto error4; /* MULTI-THREAD: ASSERT LOCK ON IDPAIRS HERE!!!! */ _mlock( _POPEN_LOCK ); /* next, set locidpair to a free entry in the idpairs table. */ if ( (locidpair = idtab( NULL )) == NULL ) goto error5; /* temporarily change the osfhnd and osfile entries so that * the child doesn't get any entries for phdls[i2]. */ osfhndsv2 = _osfhnd( phdls[i2] ); _osfhnd( phdls[i2] ) = (long)INVALID_HANDLE_VALUE; osfilesv2 = _osfile( phdls[i2] ); _osfile( phdls[i2] ) = 0; /* spawn the child copy of cmd.exe. the algorithm is adapted from * SYSTEM.C, and behaves the same way. */ if ( ((cmdexe = _tgetenv(_T("COMSPEC"))) == NULL) || (((childhnd = _tspawnl( _P_NOWAIT, cmdexe, cmdexe, _T("/c"), cmdstring, NULL )) == -1) && ((errno == ENOENT) || (errno == EACCES))) ) { /* * either COMSPEC wasn't defined, or the spawn failed because * cmdexe wasn't found or was inaccessible. in either case, try to * spawn "cmd.exe" (Windows NT) or "command.com" (Windows 95) instead * Note that spawnlp is used here so that the path is searched. */ cmdexe = ( _osver & 0x8000 ) ? _T("command.com") : _T("cmd.exe"); childhnd = _tspawnlp( _P_NOWAIT, cmdexe, cmdexe, _T("/c"), cmdstring, NULL); } _osfhnd( phdls[i2] ) = osfhndsv2; _osfile( phdls[i2] ) = osfilesv2; /* check if the last (perhaps only) spawn attempt was successful */ if ( childhnd == -1 ) goto error6; /* restore stdhdl for the current process, set value of *locidpair, * close osfhndsv1 (note that CloseHandle must be used instead of close) * and return pstream to the caller */ (void)DuplicateHandle( prochnd, osfhndsv1, prochnd, &newhnd, 0L, TRUE, /* inheritable */ DUPLICATE_CLOSE_SOURCE | /* close osfhndsv1 */ DUPLICATE_SAME_ACCESS ); (void)CloseHandle( (HANDLE)_osfhnd(stdhdl) ); _free_osfhnd( stdhdl ); _set_osfhnd( stdhdl, (long)newhnd ); _osfile(stdhdl) = osfilesv1; /* MULTI-THREAD: RELEASE LOCK ON STDHDL HERE!!!! */ _unlock_fh( stdhdl ); locidpair->prochnd = childhnd; locidpair->stream = pstream; /* MULTI-THREAD: RELEASE LOCK ON IDPAIRS HERE!!!! */ _munlock( _POPEN_LOCK ); /* all successful calls to _popen return to the caller via this return * statement! */ return( pstream ); /** * error handling code. all detected errors end up here, entering * via a goto one of the labels. note that the logic is currently * a straight fall-thru scheme (e.g., if entered at error5, the * code for error5, error4,...,error1 is all executed). **********************************************************************/ error6: /* make sure locidpair is reusable */ locidpair->stream = NULL; error5: /* close pstream (also, clear ph_open[i2] since the stream * close will also close the pipe handle) */ (void)fclose( pstream ); ph_open[ i2 ] = 0; /* MULTI-THREAD: RELEASE LOCK ON IDPAIRS HERE!!!! */ _munlock(_POPEN_LOCK); error4: /* restore stdhdl */ (void)DuplicateHandle( prochnd, osfhndsv1, prochnd, &newhnd, 0L, TRUE, DUPLICATE_SAME_ACCESS ); (void)CloseHandle( (HANDLE)_osfhnd(stdhdl) ); _free_osfhnd( stdhdl ); _set_osfhnd( stdhdl, (long)newhnd ); _osfile( stdhdl ) = osfilesv1; /* MULTI-THREAD: RELEASE LOCK ON STDHDL HERE!!!! */ _unlock_fh( stdhdl ); error3: /* close osfhndsv1 */ CloseHandle( osfhndsv1 ); error2: /* close handles on pipe (if they are still open) */ if ( ph_open[i1] ) _close( phdls[i1] ); if ( ph_open[i2] ) _close( phdls[i2] ); error1: /* return NULL to the caller indicating failure */ return( NULL ); }
void TestRegUtils::setUp() { CStdString sArgs(_T(" /s \"") + CTestUtils::GetTestFileFolder() + _T("TestRegUtils\\dv25_163cu.reg") + _T("\"")); CStdString sRegEditPath = SystemFolderInfo::GetWindowsPath() + _T("\\regedit.exe"); _tspawnlp( _P_WAIT, sRegEditPath.c_str(), sRegEditPath.c_str(), sArgs.c_str(), NULL ); }
int AppTests::RunApp(const TCHAR* sAppName) { return (x64_int_cast)_tspawnlp(_P_WAIT,sAppName,_T("/AutoRunTests"), _T("/AutoRunTests"), _T("/FunctionalTests"), NULL); }