// Run a program completely detached from the current process // it runs independantly. Program does not suspend until it completes. // No way at all to know if the program works or fails. SYSTEM_PROC( PTASK_INFO, LaunchPeerProgramExx )( CTEXTSTR program, CTEXTSTR path, PCTEXTSTR args , int flags , TaskOutput OutputHandler , TaskEnd EndNotice , uintptr_t psv DBG_PASS ) { PTASK_INFO task; if( program && program[0] ) { #ifdef WIN32 int launch_flags = ( ( flags & LPP_OPTION_NEW_CONSOLE ) ? CREATE_NEW_CONSOLE : 0 ) | ( ( flags & LPP_OPTION_NEW_GROUP ) ? CREATE_NEW_PROCESS_GROUP : 0 ) ; PVARTEXT pvt = VarTextCreateEx( DBG_VOIDRELAY ); PTEXT cmdline; PTEXT final_cmdline; LOGICAL needs_quotes; TEXTSTR expanded_path = ExpandPath( program ); char *new_path; TEXTSTR expanded_working_path = path?ExpandPath( path ):ExpandPath( WIDE(".") ); int first = TRUE; //TEXTCHAR saved_path[256]; task = (PTASK_INFO)AllocateEx( sizeof( TASK_INFO ) DBG_RELAY ); MemSet( task, 0, sizeof( TASK_INFO ) ); task->psvEnd = psv; task->EndNotice = EndNotice; if( l.ExternalFindProgram ) { new_path = l.ExternalFindProgram( expanded_path ); if( new_path ) { Release( expanded_path ); expanded_path = new_path; } } #ifdef _DEBUG xlprintf(LOG_NOISE)( WIDE("%s[%s]"), path, expanded_working_path ); #endif if( StrCmp( path, WIDE(".") ) == 0 ) { path = NULL; Release( expanded_working_path ); expanded_working_path = NULL; } if( expanded_path && StrChr( expanded_path, ' ' ) ) needs_quotes = TRUE; else needs_quotes = FALSE; if( needs_quotes ) vtprintf( pvt, WIDE( "\"" ) ); /* if( !IsAbsolutePath( expanded_path ) && expanded_working_path ) { //lprintf( "needs working path too" ); vtprintf( pvt, WIDE("%s/"), expanded_working_path ); } */ vtprintf( pvt, WIDE("%s"), expanded_path ); if( needs_quotes ) vtprintf( pvt, WIDE( "\"" ) ); if( flags & LPP_OPTION_FIRST_ARG_IS_ARG ) ; else { if( args && args[0] )// arg[0] is passed with linux programs, and implied with windows. args++; } while( args && args[0] ) { if( args[0][0] == 0 ) vtprintf( pvt, WIDE( " \"\"" ) ); else if( StrChr( args[0], ' ' ) ) vtprintf( pvt, WIDE(" \"%s\""), args[0] ); else vtprintf( pvt, WIDE(" %s"), args[0] ); first = FALSE; args++; } cmdline = VarTextGet( pvt ); vtprintf( pvt, WIDE( "cmd.exe /c %s" ), GetText( cmdline ) ); final_cmdline = VarTextGet( pvt ); VarTextDestroy( &pvt ); MemSet( &task->si, 0, sizeof( STARTUPINFO ) ); task->si.cb = sizeof( STARTUPINFO ); #ifdef _DEBUG xlprintf(LOG_NOISE)( WIDE( "quotes?%s path [%s] program [%s] [cmd.exe (%s)]"), needs_quotes?WIDE( "yes"):WIDE( "no"), expanded_working_path, expanded_path, GetText( final_cmdline ) ); #endif /* if( path ) { GetCurrentPath( saved_path, sizeof( saved_path ) ); SetCurrentPath( path ); } */ task->OutputEvent = OutputHandler; if( OutputHandler ) { SECURITY_ATTRIBUTES sa; sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; sa.nLength = sizeof( sa ); CreatePipe( &task->hReadOut, &task->hWriteOut, &sa, 0 ); //CreatePipe( &hReadErr, &hWriteErr, &sa, 0 ); CreatePipe( &task->hReadIn, &task->hWriteIn, &sa, 0 ); task->si.hStdInput = task->hReadIn; task->si.hStdError = task->hWriteOut; task->si.hStdOutput = task->hWriteOut; task->si.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; if( !( flags & LPP_OPTION_DO_NOT_HIDE ) ) task->si.wShowWindow = SW_HIDE; else task->si.wShowWindow = SW_SHOW; } else { task->si.dwFlags |= STARTF_USESHOWWINDOW; if( !( flags & LPP_OPTION_DO_NOT_HIDE ) ) task->si.wShowWindow = SW_HIDE; else task->si.wShowWindow = SW_SHOW; } { HINSTANCE hShellProcess = 0; int success = 0; #ifdef WIN32 if( flags & LPP_OPTION_IMPERSONATE_EXPLORER ) { HANDLE hExplorer = GetImpersonationToken(); if( ( CreateProcessAsUser( hExplorer, NULL //program , GetText( cmdline ) , NULL, NULL, TRUE , launch_flags | CREATE_NEW_PROCESS_GROUP , NULL , expanded_working_path , &task->si , &task->pi ) || FixHandles(task) || DumpError() ) || ( CreateProcessAsUser( hExplorer, program , GetText( cmdline ) , NULL, NULL, TRUE , launch_flags | CREATE_NEW_PROCESS_GROUP , NULL , expanded_working_path , &task->si , &task->pi ) || FixHandles(task) || DumpError() ) || ( CreateProcessAsUser( hExplorer, program , NULL // GetText( cmdline ) , NULL, NULL, TRUE , launch_flags | CREATE_NEW_PROCESS_GROUP , NULL , expanded_working_path , &task->si , &task->pi ) || FixHandles(task) || DumpError() ) || ( CreateProcessAsUser( hExplorer, WIDE( "cmd.exe" ) , GetText( final_cmdline ) , NULL, NULL, TRUE , launch_flags | CREATE_NEW_PROCESS_GROUP , NULL , expanded_working_path , &task->si , &task->pi ) || FixHandles(task) || DumpError() ) ) { success = 1; } CloseHandle( hExplorer ); } else #endif { if( ( CreateProcess( NULL //program , GetText( cmdline ) , NULL, NULL, TRUE , launch_flags | ( OutputHandler?CREATE_NO_WINDOW:0 )//CREATE_NEW_PROCESS_GROUP , NULL , expanded_working_path , &task->si , &task->pi ) || FixHandles(task) || DumpError() ) || ( CreateProcess( program , GetText( cmdline ) , NULL, NULL, TRUE , launch_flags | ( OutputHandler?CREATE_NO_WINDOW:0 )//CREATE_NEW_PROCESS_GROUP , NULL , expanded_working_path , &task->si , &task->pi ) || FixHandles(task) || DumpError() ) || ( CreateProcess( program , NULL // GetText( cmdline ) , NULL, NULL, TRUE , launch_flags | ( OutputHandler?CREATE_NO_WINDOW:0 )//CREATE_NEW_PROCESS_GROUP , NULL , expanded_working_path , &task->si , &task->pi ) || FixHandles(task) || DumpError() ) || ( TryShellExecute( task, expanded_working_path, program, cmdline ) ) || ( CreateProcess( NULL//WIDE( "cmd.exe" ) , GetText( final_cmdline ) , NULL, NULL, TRUE , launch_flags | ( OutputHandler?CREATE_NO_WINDOW:0 )//CREATE_NEW_PROCESS_GROUP , NULL , expanded_working_path , &task->si , &task->pi ) || FixHandles(task) || DumpError() ) || 0 ) { success = 1; } } if( success ) { //CloseHandle( task->hReadIn ); //CloseHandle( task->hWriteOut ); #ifdef _DEBUG xlprintf(LOG_NOISE)( WIDE("Success running %s[%s] in %s (%p): %d"), program, GetText( cmdline ), expanded_working_path, task->pi.hProcess, GetLastError() ); #endif if( OutputHandler ) { task->hStdIn.handle = task->hWriteIn; task->hStdIn.pLine = NULL; //task->hStdIn.pdp = pdp; task->hStdIn.hThread = 0; task->hStdIn.bNextNew = TRUE; task->hStdOut.handle = task->hReadOut; task->hStdOut.pLine = NULL; //task->hStdOut.pdp = pdp; task->hStdOut.bNextNew = TRUE; task->hStdOut.hThread = ThreadTo( HandleTaskOutput, (uintptr_t)task ); ThreadTo( WaitForTaskEnd, (uintptr_t)task ); } else { //task->hThread = ThreadTo( WaitForTaskEnd, (uintptr_t)task ); } } else { xlprintf(LOG_NOISE)( WIDE("Failed to run %s[%s]: %d"), program, GetText( cmdline ), GetLastError() ); CloseHandle( task->hWriteIn ); CloseHandle( task->hReadIn ); CloseHandle( task->hWriteOut ); CloseHandle( task->hReadOut ); CloseHandle( task->pi.hProcess ); CloseHandle( task->pi.hThread ); Release( task ); task = NULL; } } LineRelease( cmdline ); LineRelease( final_cmdline ); Release( expanded_working_path ); Release( expanded_path ); /* if( path ) SetCurrentPath( saved_path ); */ return task; #endif #ifdef __LINUX__ { pid_t newpid; TEXTCHAR saved_path[256]; xlprintf(LOG_ALWAYS)( WIDE("Expand Path was not implemented in linux code!") ); task = (PTASK_INFO)Allocate( sizeof( TASK_INFO ) ); MemSet( task, 0, sizeof( TASK_INFO ) ); task->psvEnd = psv; task->EndNotice = EndNotice; task->OutputEvent = OutputHandler; if( OutputHandler ) { pipe(task->hStdIn.pair); task->hStdIn.handle = task->hStdIn.pair[1]; pipe(task->hStdOut.pair); task->hStdOut.handle = task->hStdOut.pair[0]; } // always have to thread to taskend so waitpid can clean zombies. ThreadTo( WaitForTaskEnd, (uintptr_t)task ); if( path ) { GetCurrentPath( saved_path, sizeof( saved_path ) ); SetCurrentPath( path ); } if( !( newpid = fork() ) ) { char *_program = CStrDup( program ); // in case exec fails, we need to // drop any registered exit procs... //close( task->hStdIn.pair[1] ); //close( task->hStdOut.pair[0] ); //close( task->hStdErr.pair[0] ); if( OutputHandler ) { dup2( task->hStdIn.pair[0], 0 ); dup2( task->hStdOut.pair[1], 1 ); dup2( task->hStdOut.pair[1], 2 ); } DispelDeadstart(); //usleep( 100000 ); execve( _program, (char *const*)args, environ ); lprintf( WIDE( "Direct execute failed... trying along path..." ) ); { char *tmp = strdup( getenv( "PATH" ) ); char *tok; for( tok = strtok( tmp, ":" ); tok; tok = strtok( NULL, ":" ) ) { char fullname[256]; snprintf( fullname, sizeof( fullname ), "%s/%s", tok, _program ); lprintf( WIDE( "program:[%s]" ), fullname ); ((char**)args)[0] = fullname; execve( fullname, (char*const*)args, environ ); } Release( tmp ); } if( OutputHandler ) { close( task->hStdIn.pair[0] ); close( task->hStdOut.pair[1] ); } //close( task->hWriteErr ); close( 0 ); close( 1 ); close( 2 ); lprintf( WIDE( "exec failed - and this is ALLL bad... %d" ), errno ); //DebugBreak(); // well as long as this runs before // the other all will be well... task = NULL; // shit - what can I do now?! exit(0); // just in case exec fails... need to fault this. } else { if( OutputHandler ) { close( task->hStdIn.pair[0] ); close( task->hStdOut.pair[1] ); } } if( OutputHandler ) ThreadTo( HandleTaskOutput, (uintptr_t)task ); task->pid = newpid; lprintf( WIDE("Forked, and set the pid..") ); // how can I know if the command failed? // well I can't - but the user's callback will be invoked // when the above exits. if( path ) { // if path is NULL we didn't change the path... SetCurrentPath( saved_path ); } return task; } #endif } return FALSE; }
int ScanFilesEx ( CTEXTSTR base , CTEXTSTR mask , void **pInfo , void CPROC Process( uintptr_t psvUser, CTEXTSTR name, int flags ) , int flags , uintptr_t psvUser , LOGICAL begin_sub_path , struct file_system_mounted_interface *mount ) { PMFD pDataCurrent = (PMFD)(pInfo); PMFD pData = (PMFD)(*pInfo); TEXTSTR tmp_base = NULL; int sendflags; int processed = 0; #ifndef WIN32 struct dirent *de; #endif if( begin_sub_path ) { pInfo = (void**)&(pDataCurrent->current); } else pDataCurrent = NULL; //lprintf( "Search in %s for %s %d %d", base?base:"(NULL)", mask?mask:"(*)", (*pInfo)?((PMFD)*pInfo)->scanning_mount:0, (*pInfo)?((PMFD)*pInfo)->single_mount:0 ); if( !*pInfo || begin_sub_path || ((PMFD)*pInfo)->new_mount ) { TEXTCHAR findmask[256]; pData = (PMFD)(*pInfo); if( !pData ) { *pInfo = Allocate( sizeof( MFD ) ); pData = (PMFD)(*pInfo); if( !( pData->scanning_mount = mount ) ) { if( !winfile_local ) SimpleRegisterAndCreateGlobal( winfile_local ); //lprintf( "... %p", winfile_local ); pData->single_mount = FALSE; pData->scanning_mount = (*winfile_local).mounted_file_systems; } else pData->single_mount = TRUE; if( !pData->scanning_mount ) { Deallocate( PMFD, pData ); if( tmp_base ) Release( tmp_base ); return 0; } if( pData->scanning_mount->fsi ) { //lprintf( "create cursor" ); tmp_base = ExpandPathEx( base, pData->scanning_mount->fsi ); pData->cursor = pData->scanning_mount->fsi->find_create_cursor( pData->scanning_mount->psvInstance, CStrDup( tmp_base ), CStrDup( mask ) ); } else { //lprintf( "no cursor" ); pData->cursor = NULL; } } else { if( pData->new_mount ) { if( pData->scanning_mount->fsi ) { //lprintf( "create cursor (new mount)" ); tmp_base = ExpandPathEx( base, pData->scanning_mount->fsi ); pData->cursor = pData->scanning_mount->fsi->find_create_cursor( pData->scanning_mount->psvInstance, CStrDup( tmp_base ), CStrDup( mask ) ); } else pData->cursor = NULL; } } pData->new_mount = FALSE; pData->current = NULL; pData->prior = pDataCurrent; if( pDataCurrent ) { pData->root_info = pDataCurrent->root_info; pInfo = (void**)pData->root_info; } else { pData->root_info = (struct myfinddata**)pInfo; } (*pData->root_info) = pData; if( base ) { TEXTSTR tmp; StrCpyEx( findbasename(pInfo), tmp = ExpandPathEx( base, pData->scanning_mount?pData->scanning_mount->fsi:NULL ), MAX_PATH_NAME ); Release( tmp ); StrCpyEx( findmask(pInfo), mask, MAX_PATH_NAME ); } else { CTEXTSTR p = pathrchr( mask ); if( p ) { StrCpyEx( findbasename(pInfo), mask, p - mask + 1 ); StrCpyEx( findmask(pInfo), p + 1, MAX_PATH_NAME ); //mask = p + 1; } else { StrCpyEx( findbasename(pInfo), WIDE(""), 2 ); StrCpyEx( findmask(pInfo), mask, MAX_PATH_NAME ); } } if( findbasename(pInfo)[0] ) tnprintf( findmask, sizeof(findmask), WIDE("%s/*"), findbasename(pInfo) ); else tnprintf( findmask, sizeof( findmask ), WIDE( "*" ) ); if( pData->scanning_mount?pData->scanning_mount->fsi:NULL ) if( pData->scanning_mount->fsi->find_first( findcursor(pInfo) ) ) findhandle(pInfo) = 0; else findhandle(pInfo) = (HANDLECAST)-1; else { #if WIN32 findhandle(pInfo) = findfirst( findmask, finddata(pInfo) ); #else //lprintf( "opendir %s", findbasename(pInfo) ); findhandle( pInfo ) = opendir( findbasename(pInfo) ); if( !findhandle(pInfo ) ) findhandle(pInfo) = (HANDLECAST)-1; else de = readdir( (DIR*)findhandle( pInfo ) ); #endif } if( findhandle(pInfo) == (HANDLECAST)-1 ) { PMFD prior = pData->prior; //lprintf( "first use of cursor or first open of directoy failed..." ); if( pData->scanning_mount && pData->scanning_mount->fsi ) pData->scanning_mount->fsi->find_close( (struct find_cursor*)findcursor(pInfo) ); else { #ifdef WIN32 findclose( findhandle(pInfo) ); #else // but it failed... so ... don't close //closedir( findhandle( pInfo ) ); #endif } pData->scanning_mount = NextThing( pData->scanning_mount ); if( !pData->scanning_mount || pData->single_mount ) { (*pData->root_info) = pData->prior; if( !begin_sub_path ) { Release( pData ); pInfo[0] = NULL; } //lprintf( WIDE( "%p %d" ), prior, processed ); if( tmp_base ) Release( tmp_base ); return prior?processed:0; } pData->new_mount = TRUE; if( tmp_base ) Release( tmp_base ); return 1; } } else { int r; getnext: //lprintf( "returning customer..." ); if( pData->scanning_mount?pData->scanning_mount->fsi:NULL ) r = !pData->scanning_mount->fsi->find_next( findcursor( pInfo ) ); else { #ifdef _WIN32 r = findnext( findhandle(pInfo), finddata( pInfo ) ); #else de = readdir( (DIR*)findhandle( pInfo ) ); //lprintf( "using %p got %p", findhandle( pInfo ), de ); r = (de == NULL); #endif } if( r ) { PMFD prior = pData->prior; //lprintf( "nothing left to find..." ); if( pData->scanning_mount->fsi ) pData->scanning_mount->fsi->find_close( findcursor(pInfo) ); else { #ifdef WIN32 findclose( findhandle(pInfo) ); #else closedir( (DIR*)findhandle(pInfo)); #endif } pData->scanning_mount = NextThing( pData->scanning_mount ); //lprintf( "Step mount... %p %d", pData->scanning_mount, pData->single_mount ); if( !pData->scanning_mount || pData->single_mount ) { //lprintf( "done with mounts?" ); (*pData->root_info) = pData->prior; Release( pData ); if( prior ) prior->current = NULL; if( !processed && !begin_sub_path ) { //pInfo = (void**)&(prior->prior->current); pData = prior; if( pData ) goto getnext; } if( tmp_base ) Release( tmp_base ); return (*pInfo)?processed:0; } pData->new_mount = TRUE; if( tmp_base ) Release( tmp_base ); return 1; } } if( pData->scanning_mount?pData->scanning_mount->fsi:NULL ) { char * path = pData->scanning_mount->fsi->find_get_name( findcursor(pInfo) ); //lprintf( "... %s", path ); if( !strcmp( ".", path ) || !strcmp( "..", path ) ) goto getnext; } else { #if WIN32 //lprintf( "... %s", finddata(pInfo)->name ); # ifdef UNDER_CE if( !StrCmp( WIDE("."), finddata(pInfo)->cFileName ) || !StrCmp( WIDE(".."), finddata(pInfo)->cFileName ) ) # else if( !StrCmp( WIDE("."), finddata(pInfo)->name ) || !StrCmp( WIDE(".."), finddata(pInfo)->name ) ) # endif #else if( !StrCmp( WIDE("."), de->d_name ) || !StrCmp( WIDE(".."), de->d_name ) ) #endif goto getnext; } if( !(flags & SFF_NAMEONLY) ) // if nameonly - have to rebuild the correct name. { if( pData->scanning_mount?pData->scanning_mount->fsi:NULL ) { tnprintf( pData->file_buffer, MAX_PATH_NAME, WIDE("%s"), pData->scanning_mount->fsi->find_get_name( findcursor(pInfo) ) ); if( findbasename( pInfo )[0] ) tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s/%s"), findbasename(pInfo), pData->file_buffer ); else tnprintf( pData->buffer, MAX_PATH_NAME, WIDE( "%s" ), pData->file_buffer ); } else { #ifdef WIN32 # ifdef UNDER_CE tnprintf( pData->file_buffer, MAX_PATH_NAME, WIDE( "%s" ), finddata( pInfo )->cFileName ); tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s/%s"), findbasename(pInfo), finddata(pInfo)->cFileName ); # else tnprintf( pData->file_buffer, MAX_PATH_NAME, WIDE("%s"), finddata(pInfo)->name ); tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s%s%s"), findbasename(pInfo), findbasename( pInfo )[0]?"/":"", pData->file_buffer ); # endif #else tnprintf( pData->file_buffer, MAX_PATH_NAME, WIDE("%s"), de->d_name ); tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s/%s"), findbasename(pInfo), de->d_name ); #endif } } else { if( flags & SFF_SUBCURSE ) { if( pData->scanning_mount?pData->scanning_mount->fsi:NULL ) { tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s%s%s") , pData->prior?pData->prior->buffer:WIDE( "" ) , pData->prior?WIDE( "/" ):WIDE( "" ) , pData->scanning_mount->fsi->find_get_name( findcursor(pInfo) ) ); } else { #if WIN32 # ifdef UNDER_CE tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s%s%s") , pData->prior?pData->prior->buffer:WIDE( "" ) , pData->prior?WIDE( "/" ):WIDE( "" ) , finddata(pInfo)->cFileName ); # else tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s%s%s") , pData->prior?pData->prior->buffer:WIDE( "" ) , pData->prior?WIDE( "/" ):WIDE( "" ) , finddata(pInfo)->name ); # endif #else tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s%s%s") , pData->prior?pData->prior->buffer:WIDE( "" ) , pData->prior?WIDE( "/" ):WIDE( "" ) , de->d_name ); lprintf( "resulting is %s", pData->buffer ); #endif } } else { if( pData->scanning_mount?pData->scanning_mount->fsi:NULL ) { tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s"), pData->scanning_mount->fsi->find_get_name( findcursor(pInfo) ) ); } else { #if WIN32 # ifdef UNDER_CE tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s"), finddata(pInfo)->cFileName ); # else # ifdef UNICODE snwprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s"), finddata(pInfo)->name ); # else tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s"), finddata(pInfo)->name ); # endif # endif #else tnprintf( pData->buffer, MAX_PATH_NAME, WIDE("%s"), de->d_name ); #endif } } } pData->buffer[MAX_PATH_NAME-1] = 0; // force nul termination... #ifdef UNICODE { char *pDataBuffer = CStrDup( pData->buffer ); #else # define pDataBuffer pData->buffer #endif //lprintf( "Check if %s is a directory...", pData->buffer ); if( (flags & (SFF_DIRECTORIES | SFF_SUBCURSE)) && (pData->scanning_mount && pData->scanning_mount->fsi && (pData->scanning_mount->fsi->is_directory && pData->scanning_mount->fsi->is_directory( pDataBuffer ))) || (!(pData->scanning_mount ? pData->scanning_mount->fsi : NULL) #ifdef WIN32 # ifdef UNDER_CE && (finddata( pInfo )->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) # else && (finddata( pInfo )->attrib & _A_SUBDIR) # endif #else && IsPath( pData->buffer ) #endif ) ) { #ifdef UNICODE Deallocate( char *, pDataBuffer ); #else # undef pDataBuffer #endif //lprintf( "... it is?" ); if( flags & SFF_DIRECTORIES ) { if( Process != NULL ) { //lprintf( "Send %s", pData->buffer ); Process( psvUser, pData->buffer, SFF_DIRECTORY ); processed = 1; } //return 1; } if( flags & SFF_SUBCURSE ) { void *data = NULL; int ofs = 0; TEXTCHAR tmpbuf[MAX_PATH_NAME]; if( flags & SFF_NAMEONLY ) { // even in name only - need to have this full buffer for subcurse. if( pData->scanning_mount && pData->scanning_mount->fsi ) { ofs = tnprintf( tmpbuf, sizeof( tmpbuf ), WIDE( "%s/%s" ), findbasename( pInfo ), pData->scanning_mount->fsi->find_get_name( findcursor( pInfo ) ) ); } else { #ifdef WIN32 # ifdef UNDER_CE ofs = tnprintf( tmpbuf, sizeof( tmpbuf ), WIDE( "%s/%s" ), findbasename( pInfo ), finddata( pInfo )->cFileName ); # else # ifdef UNICODE ofs = snwprintf( tmpbuf, sizeof( tmpbuf ), WIDE( "%s/%s" ), findbasename( pInfo ), finddata( pInfo )->name ); # else ofs = tnprintf( tmpbuf, sizeof( tmpbuf ), WIDE( "%s/%s" ), findbasename( pInfo ), finddata( pInfo )->name ); # endif # endif #else ofs = tnprintf( tmpbuf, sizeof( tmpbuf ), WIDE( "%s/%s" ), findbasename( pInfo ), de->d_name ); #endif } //lprintf( "process sub... %s %s", tmpbuf, findmask(pInfo) ); processed |= ScanFilesEx( tmpbuf, findmask( pInfo ), (POINTER*)pData, Process, flags, psvUser, TRUE, pData->scanning_mount ); } else { //lprintf( "process sub..." ); processed |= ScanFilesEx( pData->buffer, findmask( pInfo ), (POINTER*)pData, Process, flags, psvUser, TRUE, pData->scanning_mount ); } } if( !processed ) goto getnext; if( tmp_base ) Release( tmp_base ); return (*pInfo) ? 1 : 0; } #ifdef UNICODE Deallocate( char *, pDataBuffer ); } #else # undef pDataBuffer #endif if( ( sendflags = SFF_DIRECTORY, ( ( flags & SFF_DIRECTORIES ) #ifdef WIN32 # ifdef UNDER_CE && ( finddata(pInfo)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) # else && ( finddata(pInfo)->attrib & _A_SUBDIR ) # endif #else && ( IsPath( pData->buffer ) ) #endif ) ) || ( sendflags = 0, CompareMask( findmask( pInfo ) #ifdef WIN32 # ifdef UNDER_CE , finddata(pInfo)->cFileName # else , pData->file_buffer # endif #else , de->d_name #endif // yes this is silly - but it's correct... , (flags & SFF_IGNORECASE)?0:0 ) ) ) { //lprintf( "Send %s", pData->buffer ); if( Process != NULL ) Process( psvUser, pData->buffer, sendflags ); if( tmp_base ) Release( tmp_base ); return (*pInfo)?1:0; } if( tmp_base ) Release( tmp_base ); return (*pInfo)?1:0; }