void platform_init() { char buffer[512] = {0}; /* this environment variable is set by Microsoft Visual Studio when building. It causes cl.exe to redirect it's output to the specified pipe id. this causes loads of problems with output. */ SetEnvironmentVariable("VS_UNICODE_OUTPUT", NULL); /* check if we are being spawned by bam in msvc mode so we should be singleton */ if(GetEnvironmentVariable("BAM_SINGLETON", buffer, sizeof(buffer)-1)) { DWORD ret; SetEnvironmentVariable("BAM_SINGLETON", NULL); singleton_mutex = CreateMutex(NULL, FALSE, "Global\\bam_singleton_mutex"); if(!singleton_mutex) { printf("bam is already running, wait for it to finish and then try again 1\n"); exit(1); } while(1) { ret = WaitForSingleObject( singleton_mutex, 100 ); if(ret == WAIT_OBJECT_0) break; else { /* printf("bam is already running, wait for it to finish and then try again 2 (%d)\n", ret); */ printf("bam is already running, waiting for it to finish\n"); fflush(stdout); Sleep(1000); } } } /* this environment variable can be setup so that bam can observe if a specific process dies and abort the building if it does. This is used in conjunction with Microsoft Visual Studio to make sure that it doesn't kill processes wildly. */ if(GetEnvironmentVariable("BAM_OBSERVE_PID", buffer, sizeof(buffer)-1)) { observe_pid = atoi(buffer); threads_create(observer_thread, NULL); /* protect process from being killed */ protect_process(); } else { if( session.win_msvcmode ) { DWORD errcode; PROCESS_INFORMATION pi; STARTUPINFO si; /* setup ourself to be watched */ sprintf(buffer, "%d", GetCurrentProcessId()); SetEnvironmentVariable("BAM_OBSERVE_PID", buffer); /* signal that we want to be singleton */ SetEnvironmentVariable("BAM_SINGLETON", "1"); /* init structs and create process */ ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); if( CreateProcess( NULL, /* No module name (use command line) */ GetCommandLine(), /* Command line */ NULL, /* Process handle not inheritable */ NULL, /* Thread handle not inheritable */ TRUE, /* Set handle inheritance to FALSE */ 0, /* No creation flags */ NULL, /* Use parent's environment block */ NULL, /* Use parent's starting directory */ &si, /* Pointer to STARTUPINFO structure */ &pi /* Pointer to PROCESS_INFORMATION structure */ ) ) { /* wait for the child to complete */ WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &errcode); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); exit(errcode); } else { printf("failed to spawn new bam process in msvc mode\n"); printf("%s\n", GetCommandLine()); exit(1); } } } InitializeCriticalSection(&criticalsection); }
void protect_processes ( List &black_list , List &black_list_checks , List &processes , List &uptimes ) { unsigned int checking_counter; unsigned int uptime; unsigned int cont; unsigned int pos; int pid; int ret; /* Walking process list */ for ( cont = 0 ; cont < processes.Len () ; cont ++ ) { /* Next PID */ pid = ( int ) processes.Get ( cont ); /* Process Uptime */ uptime = ( unsigned int ) uptimes.Get ( cont ); // printf ( "%i: %u seconds\n" , pid , uptime ); /* If the UPTIME is ENOUGH */ if ( uptime >= GOOD_UPTIME ) { /* If the process is in the BLACK LIST */ if ( black_list.Find ( ( void * ) pid ) == TRUE ) { /* Getting the position in the list */ black_list.GetPos ( ( void * ) pid , &pos ); /* Getting the times that the process was attempted to be preotected */ checking_counter = ( unsigned int ) black_list_checks.Get ( pos ); /* If the "time to protect" is fine */ if ( checking_counter < MAX_TRIES ) { /* Trying to protect the process */ ret = protect_process ( pid ); /* If the process could be protected */ if ( ret == 1 ) { /* Process protected */ black_list_checks.Set ( pos , ( void * ) MAX_TRIES ); } else { /* Incrementing the counter protection tries */ black_list_checks.Set ( pos , ( void * ) ( checking_counter + 1 ) ); } } } else { /* Trying to protect the process */ ret = protect_process ( pid ); /* Adding the process to the BLACK LIST */ black_list.Add ( ( void * ) pid ); /* If the process could be protected */ if ( ret == 1 ) { /* Process protected */ black_list_checks.Add ( ( void * ) MAX_TRIES ); } /* If the process couldn't be protected */ else { /* To be scanned again */ black_list_checks.Add ( ( void * ) 1 ); } } } } }