This is the function in question...

What happens is the user opens notepad, if notepad is open then they are required to type a password.. If its invalid, notepad is closed.. if the password is valid, it continues.. else if the user hasn't entered a password within 10 seconds, timeout..

So the function works when the password is valid/invalid.. the problem is when the user times out, and they open notepad again, they cannot enter the password as it wont allow them..

Try compiling the attached .cpp file and see what I mean..

void pwget()
{    
     string password;
     password.clear();
     REPEAT
     char cProcess[80] = "notepad.exe";
     DWORD dwReturn;
     dwReturn = CountProcesses(cProcess);
     if(dwReturn != -1)
     {
                           if(dwReturn == 1)
                           {
                              cout<<"User Attempted to Open Program!\n\n";
                              
                              using namespace jsw::threading;
                              char pword[1024];
                              auto_event e;
                              LPVOID args[2] = {pword, &e};
                              thread worker = thread::start(get_password, args);
                              
                              if (e.wait(10000)){
                              string password(pword);
                                 if(password == "brandon")
                                 {
                                  system("cls");
                                  cout<<"Password was entered correctly.\n\n";
                                  Sleep(1000);
                                  system("cls");
                                  break;
                                  }
                                  else
                                  {
                                      system("cls");
                                      cout<<"Password is Invalid...\n\n";
                                      Sleep(1000);
                                      system("taskkill /IM notepad.exe");
                                      cout<<"\n";
                                      system("cls");
                                      cout<<"Welcome to GameBlock v1.0\n\n";
                                      pwget();
                                  }
                              }
                              else {
                              worker.abort(NO_ERROR);
                              cout<<"\n\nUser Timedout..\n\n";
                              Sleep(1000);
                              system("taskkill /IM notepad.exe");
                              cout<<"\n";
                              system("cls"); 
                              cout<<"Welcome to GameBlock v1.0\n\n";
                              pwget();
                              }
                           }
                           else if(dwReturn == 0)
                           {
                               cout<<"Program Not Running\n";
                               Sleep(1000);
                               main();
                           }
     }
    UNTIL((password == "brandon"));
    password.clear();
    cout<<"In Minutes, enter the length of time the program should run: ";
    cin>>x;
    cin.ignore();
    x = x*60;
}

Extra problems but not required to help fix: Timer Pause function doesnt work.. Find by me for now. I would just like help on why they cannot enter the password when it timesout.

Attachments
#define REPEAT do{
#define UNTIL( condition ) }while(!(condition));

#pragma comment(lib, "advapi32.lib")
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <conio.h>
#include <string.h>
#include <time.h>	// class needs this inclusion

using namespace std;


//////////////////////////////////////////
// class declaration:


class timer {
	public:
		timer();
		void           start();
		void           stop();
		void           reset();
		bool           isRunning();
		unsigned long  getTime();
		bool           isOver(unsigned long seconds);
	private:
		bool           resetted;
		bool           running;
		unsigned long  beg;
		unsigned long  end;
};
// End Class Declaration...

//////////////////////////////////////////
// class implementation:


timer::timer() {
	resetted = true;
	running = false;
	beg = 0;
	end = 0;
}


void timer::start() {
	if(! running) {
		if(resetted)
			beg = (unsigned long) clock();
		else
			beg -= end - (unsigned long) clock();
		running = true;
		resetted = false;
	}
}


void timer::stop() {
	if(running) {
		end = (unsigned long) clock();
		running = false;
	}
}


void timer::reset() {
	bool wereRunning = running;
	if(wereRunning)
		stop();
	resetted = true;
	beg = 0;
	end = 0;
	if(wereRunning)
		start();
}


bool timer::isRunning() {
	return running;
}


unsigned long timer::getTime() {
	if(running)
		return ((unsigned long) clock() - beg) / CLOCKS_PER_SEC;
	else
		return (end - beg) / CLOCKS_PER_SEC;
}


bool timer::isOver(unsigned long seconds) {
	return seconds >= getTime();
}
//End Class Implementation...


//Declare Check Processes...
DWORD CountProcesses(CHAR *pProcessName) 
{
    DWORD dwCount = 0;
    HANDLE hSnap = NULL;
    PROCESSENTRY32 proc32;

    if((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE)
        return -1;
    proc32.dwSize=sizeof(PROCESSENTRY32);
    while((Process32Next(hSnap, &proc32)) == TRUE)
        if(stricmp(proc32.szExeFile,pProcessName) == 0)
            ++dwCount;
    CloseHandle(hSnap); 
    return dwCount;
}
//End Declaration...
//Declare Thread...
namespace jsw {
    namespace threading {
        class auto_event {
        public:
            auto_event(): _event(CreateEvent(0, false, false, 0)) {}

            BOOL wait(DWORD timeout = 1) const
            {
                return WaitForSingleObject(_event, timeout) == WAIT_OBJECT_0;
            }

            BOOL set() { return SetEvent(_event); }
        private:
            HANDLE _event;
        };

        class thread {
        public:
            static thread start(
                LPTHREAD_START_ROUTINE fn, LPVOID args = 0, 
                DWORD state = 0, DWORD timeout = 5000)
            {
                return thread(CreateThread(0, 0, fn, args, state, 0), timeout);
            }

            static void sleep(DWORD milliseconds) { Sleep(milliseconds); }
            static void exit(DWORD exitCode) { ExitThread(exitCode); }
        public:
            thread(HANDLE thread, DWORD timeout): _thread(thread), _timeout(timeout) {}
            ~thread() { CloseHandle(_thread); }

            DWORD exit_code() const
            {
                DWORD exitCode = NO_ERROR;

                GetExitCodeThread(_thread, &exitCode);

                return exitCode;
            }

            HANDLE handle() const { return _thread; }
            BOOL is_alive() const { return exit_code() == STILL_ACTIVE; }
            DWORD join() { return WaitForSingleObject(_thread, _timeout); }
            DWORD suspend() { return SuspendThread(_thread); }
            DWORD resume() { return ResumeThread(_thread); }
            BOOL abort(DWORD exitCode) { return TerminateThread(_thread, exitCode); }
        private:
            HANDLE _thread;
            DWORD _timeout;
        };
    }
}
//End Thread Declaration
//Star Declaration for password in thread & Password output->screen = Asterisks..
DWORD WINAPI get_password(LPVOID args)
{
  using namespace jsw::threading;
 
  int ch;
  char *pword = (char*)((LPVOID*)args)[0];
  auto_event *e = (auto_event*)((LPVOID*)args)[1];
  int s = 0;
  
  puts ("Enter The Password To Allow the program to run: ");
  fflush(stdout);
  
  while ((ch = getch()) != EOF 
          && ch != '\n' 
          && ch != '\r')
  {
    if (ch == '\b' && s > 0) 
    {
      printf("\b \b");
      fflush(stdout);
      s--;
      pword[s] = '\0';
    }
    else if (isalnum(ch))
    {
      putchar('*');
      pword[s++] = (char)ch;
    }
  }

  pword[s] = '\0';
  e->set();
 
  return NO_ERROR;
}
//End Declaration for password in thread..

//////////////////////////////////////////
// class test program:

void pwget();         
void stopped();
void started();

string playagain;
int x;
int i = 0;

//int main( int, char *[] )
int main(void)
{
    system("cls");
    cout<<"Welcome to GameBlock v1.0\n\n";
    REPEAT
    pwget();
    
   	bool quit = false;
	char choice;
	timer t;
	
	while(! quit) {
            
               {
                    cout<<"Timer Started\n";  
                    started();
                    quit = true;
                    system("taskkill /IM notepad.exe");
                    cout<<"\n";
				}
		}
		cout << "------------------------------\n\n" << endl;
		cout<<"Play Again??  (y/n): \n\n";
		playagain.clear();
		cin>> playagain;
		cin.ignore();
		if((playagain == "y") || playagain == "Y")
		{
                      main();
        }
        else if ((playagain == "n") || playagain == "N")
        {
                       main();
        }
        else
        {
                       main();
        }
	UNTIL(playagain == "n");
    playagain.clear();
    system("cls");
    
    return 0;
}

void pwget()
{    
     string password;
     password.clear();
     REPEAT
     char cProcess[80] = "notepad.exe";
     DWORD dwReturn;
     dwReturn = CountProcesses(cProcess);
     if(dwReturn != -1)
     {
                           if(dwReturn == 1)
                           {
                              cout<<"User Attempted to Open Program!\n\n";
                              
                              using namespace jsw::threading;
                              char pword[1024];
                              auto_event e;
                              LPVOID args[2] = {pword, &e};
                              thread worker = thread::start(get_password, args);
                              
                              if (e.wait(10000)){
                              string password(pword);
                                 if(password == "brandon")
                                 {
                                  system("cls");
                                  cout<<"Password was entered correctly.\n\n";
                                  Sleep(1000);
                                  system("cls");
                                  break;
                                  }
                                  else
                                  {
                                      system("cls");
                                      cout<<"Password is Invalid...\n\n";
                                      Sleep(1000);
                                      system("taskkill /IM notepad.exe");
                                      cout<<"\n";
                                      system("cls");
                                      cout<<"Welcome to GameBlock v1.0\n\n";
                                      pwget();
                                  }
                              }
                              else {
                              worker.abort(NO_ERROR);
                              cout<<"\n\nUser Timedout..\n\n";
                              Sleep(1000);
                              system("taskkill /IM notepad.exe");
                              cout<<"\n";
                              system("cls"); 
                              cout<<"Welcome to GameBlock v1.0\n\n";
                              pwget();
                              }
                           }
                           else if(dwReturn == 0)
                           {
                               cout<<"Program Not Running\n";
                               Sleep(1000);
                               main();
                           }
     }
    UNTIL((password == "brandon"));
    password.clear();
    cout<<"In Minutes, enter the length of time the program should run: ";
    cin>>x;
    cin.ignore();
    x = x*60;
}

void stopped()
{
	bool quit = false;
	char choice;
	timer t;
	char cProcess[80] = "notepad.exe";
	DWORD dwReturn;
	dwReturn = CountProcesses(cProcess);
    if(dwReturn != -1)
     {
                           if(dwReturn == 0)
                           {
                              cout<<"Program Not running, User taking a break.. Timer Paused...\n\n";
                              Sleep(2000);
                              started();
                           }
                           else if(dwReturn == 1)
                           {
                                //cout<<"Program Started/Resumed.. Timer Resumed..\n\n";
                           }
     }
}

void started()
{
     bool quit = false;
	char choice;
	timer t;
	char cProcess[80] = "notepad.exe";
	DWORD dwReturn;
	dwReturn = CountProcesses(cProcess);
					do
					{
                           Sleep(1000);
                           cout <<t.getTime()/3600<<" hrs & "<< t.getTime() << " s" << endl;

                           DWORD dwReturn;
                           char cProcess[80] = "notepad.exe";
                           dwReturn = CountProcesses(cProcess);
                           if(dwReturn != -1)
                           {
                             stopped();
                             if(dwReturn == 1)
                             {

Instead of worker.abort(), use this:

keybd_event(VK_RETURN, 0x3d, 0, 0);
keybd_event(VK_RETURN, 0x3d, KEYEVENTF_KEYUP, 0);
worker.join();

The problem was that stdin was locked by getch, and terminating the thread didn't release the lock. The simplest solution I can think of is signaling a keyboard event to unlock stdin and stop the thread normally rather than abort it.

Your code is somewhat scary too, but I'll refrain from overloading you with information.

:O Didnt think of that... Yeah it looks scary with all the process checking and loops and stuff.. I'll clean it up as soon as I solve all the bugs. Usually while im coding it gets out of control and then when the program is done, it gets all neat.

Thanks again! I had a feeling you'd be the only one to reply -_-

btw how did your learn about threads?? I mean I know a little bit of it after you showed me an example but there isnt very good tutorials out there :S Or maybe Im just being difficult or blind.

btw how did your learn about threads??

Trial and error...and error, and error, and error. I'll let you know when the error part gives way to better understanding. I'm far from confident when it comes to concurrency. ;)

This question has already been answered. Start a new discussion instead.