Thread: Problem with inputting password?

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    230

    Problem with inputting password?

    Hi everyone,
    I've been writing this program and updating it for a while, but until now I can't get rid of this one bug, I can't input data from the keyboard!
    Everything used to work fine until I started using main() arguments to open files. To open a file, all you need to do is drag it onto the program's file and the program will start automatically (I'm not sure if this is standard, but the file's path is passed as an argument on Windows XP).

    Since it's an encrypting program, you obviously need to input a password, but I can't input one, neither can I press enter to continue.
    These are the functions I'm using:
    Code:
    /* input password from user */
    void getpassword(char password[], int maxlength)
    {
    	int i=0, done=0;
    	char c;
    
    	printf("Please input password (max. %d characters): ", maxlength);
    	fflush(stdout);
    
    	while (!done)
    	{
    		c = getchar();
    		switch(c)
    		{
    			case '\r':
    			case '\n':
    				done = 1;
    				break;
    			case '\b':
    				if (i > 0)		/* perform backspace only if characters have already been input */
    				{
    					printf("\b \b");
    					i--;
    				}
    				break;
    			default:
    				if (i<maxlength && isprint(c))	/* save character in password as long as it's not a none-printing character */
    				{
    					password[i++] = c;
    					putchar('*');
    				}
    				break;
    			}
    		fflush(stdout);
    	}
    	password[i] = '\0';
    }
    
    
    /* like getchar() except without echo */
    char mygetch(void)
    {
      static HANDLE hIn;
      static DWORD  NumRead;
      static INPUT_RECORD InRec;
      static char c;
    
      hIn = GetStdHandle(STD_INPUT_HANDLE);
      if(hIn == INVALID_HANDLE_VALUE)
      {
        printf("GetStdHandle poop");
      }
      else
      {
        do
        {
          ReadConsoleInput(hIn, &InRec, 5, &NumRead);
          if (InRec.EventType == KEY_EVENT)
          {
            if (InRec.Event.KeyEvent.bKeyDown == 1)
            {
              c = InRec.Event.KeyEvent.uChar.AsciiChar;
              /* testing print
              printf("  KDown  Repeat  KeyCode  ScanCode  Unicode  Ascii  Ctrl-State \n");
              printf("  %3x    %3x     %3x      %3x       %3x      %3x    %3lx \n",
                      InRec.Event.KeyEvent.bKeyDown,
                      InRec.Event.KeyEvent.wRepeatCount,
                      InRec.Event.KeyEvent.wVirtualKeyCode,
                      InRec.Event.KeyEvent.wVirtualScanCode,
                      InRec.Event.KeyEvent.uChar.UnicodeChar,
                      InRec.Event.KeyEvent.uChar.AsciiChar,
                      InRec.Event.KeyEvent.dwControlKeyState );
              */
              /* printf("|if %c %02x ", c, c);  testing*/
              break;
            }
          }
        }
        while( c !=  '\r' );
      }
      return c;
    }
    I got the mygetch() function from one of the forum members here (I think Mcgrayer or something like that) and after a lot of debugging I found that the problem is with it, because when I replaced it with getchar() it worked fine (except for the output of course). I am also aware that it only works on Windows.

    But why doesn't mygetch() work anymore?

    Please note that I also made sure my program worked if you don't drag a file onto it, but it obviously asks you for the file name and inputs it manually using fgets, and when I use this method to open the file the password input always works.

    I am using Visual C++ Express 2008.

    What's even weirder, is that the problem doesn't appear the first time you run the program, but it appears the second time with the exact same file(s).

    I don't mind giving you the source, but it's about 1000 lines and I don't think any of you have the time to do so. Of course if you can, I'd be thankful.

    Thank you,
    I might not be a pro, but I'm usually right

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    See if you have the same problem with this version - it uses _getch() from conio.h
    Code:
    #include <conio.h>
    #include <ctype.h>
    #include <stdio.h>
    
    int get_password(char *password,
                     char echo_char, /* echo character */
                     int esc_breaks, /* does hitting ESC return false? */
                     size_t buff_sz) /* is there a length limit? */
    {
        const int ESC = 27;
        const int BACKSPACE = 8;
    
        int c;
        size_t idx = 0;
    
        /* clear password*/
        *password = 0;
    
        for (;;)
        {
            c = _getch();
    
            if (c == '\r')
            {
                password[idx] = 0;
                break;
            }
    
            /* only accept printable chars */
            if (isprint(c))
            {
                if ((buff_sz == 0) ||
                    ((buff_sz != 0) && (idx < (buff_sz - 1))))
                {
                    password[idx++] = c;
                    putchar(echo_char);
                }
                else
                    putchar('\a');
            }
    
            /* support for backspace functionality */
            if (c == BACKSPACE)
            {
                if (idx != 0)
                {
                    putchar(c);   /* backspace */
                    putchar(' '); /* overwrite existing char */
                    putchar(c);   /* backspace back into position */
                    --idx;
                }
                else
                    putchar('\a');
            }
    
            if (esc_breaks && (c == ESC))
                return 0;
        }/*for*/
    
        return idx != 0;
    }/*get_password*/
    
    
    int main()
    {
        char buff[9]; // max 8 character password
    
        if (get_password(buff, '*', 1, sizeof(buff)))
            printf("\nget_password returned true - entered password is \"&#37;s\"\n", buff);
        else
            puts("\nget_password returned false\n");
    
        return 1;
    }
    gg

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    230
    Thanks for replying Codeplug.
    I totally forgot about conio.h and that it was available in MSVC++ (I previously used to use GCC).
    It's working fine now, but I'd still like to know what was wrong with the function I provided (mygetch()). It seems like a pretty weird bug to me, especially that it works sometimes and not others...
    I might not be a pro, but I'm usually right

  4. #4
    Registered User
    Join Date
    May 2008
    Posts
    2
    thanx 4 helping me . thanx a lot

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Password Program
    By lukesowersby in forum C Programming
    Replies: 2
    Last Post: 03-23-2009, 11:36 AM
  2. Input a password and replace with *s
    By Abda92 in forum C Programming
    Replies: 45
    Last Post: 10-06-2007, 03:52 PM
  3. [Q]Hide Password
    By Yuri in forum C++ Programming
    Replies: 14
    Last Post: 03-02-2006, 03:42 AM
  4. Bin packing problem....
    By 81N4RY_DR460N in forum C++ Programming
    Replies: 0
    Last Post: 08-01-2005, 05:20 AM
  5. Putting a password on the prog
    By Inferno in forum C++ Programming
    Replies: 24
    Last Post: 09-18-2004, 01:07 PM