#pragma argsused
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAXCODESIZE 100
long FAR PASCAL WndMainProc();
BOOL FAR PASCAL KeypadBox(HWND,unsigned int,WORD,DWORD);
FARPROC hfun;
FARPROC TransitHook;
FARPROC TransitCoor;
HANDLE hInst;
FARPROC lpProc;
FARPROC prevhook;
HWND mwnd;
int CODESIZE;
int top,bottom,left,right;

char buf[80];
int code[MAXCODESIZE];
int tcode[MAXCODESIZE];

int ValidCmdLine(LPSTR str)
{
 int x,c;

 if (lstrlen(str)<1 || lstrlen(str)>=MAXCODESIZE) return FALSE;
 for (x=0;x<lstrlen(str);x++)
 {
  c=toupper(str[x]);
  if ((c<'0' || c>'9') && (c<'A' || c>'F')) return FALSE;
 }
 return TRUE;
}

int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance,
		   LPSTR lpCmdLine,int CmdShow)
{
 WNDCLASS wc;
 HANDLE hAcc;
 HANDLE hLib;
 HWND hWnd;
 MSG msg;
 int x;

 if (!hPrevInstance)
 {
  wc.style=NULL;
  wc.lpfnWndProc=WndMainProc;
  wc.cbClsExtra=wc.cbWndExtra=0;
  wc.hInstance=hInstance;
  wc.hIcon=LoadIcon(hInstance,"ICON");
  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
  wc.hbrBackground=GetStockObject(WHITE_BRUSH);
  wc.lpszMenuName=NULL;
  wc.lpszClassName="ComboLockWindow";
  if (!RegisterClass(&wc)) return FALSE;
 }
 hInst=hInstance;
 hWnd=CreateWindow(  "ComboLockWindow",
		"Lock-By Kevin LaFata",
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL,
		NULL,
		hInstance,
		NULL);
 if (!hWnd) return FALSE;
 CODESIZE=lstrlen(lpCmdLine);
 if (!ValidCmdLine(lpCmdLine))
 {
  MessageBox(hWnd,"Invalid Command Line-Please See Documentation",
  "Combination Lock",MB_OK);
  return FALSE;
 }
 else
 {
  for (x=0;x<CODESIZE;x++)
  {
   switch(lpCmdLine[x])
   {
    case '1':code[x]=1;break;
    case '2':code[x]=2;break;
    case '3':code[x]=3;break;
    case '4':code[x]=4;break;
    case '5':code[x]=5;break;
    case '6':code[x]=6;break;
    case '7':code[x]=7;break;
    case '8':code[x]=8;break;
    case '9':code[x]=9;break;
    case '0':code[x]=16;break;
    case 'A':
    case 'a':code[x]=10;break;
    case 'B':
    case 'b':code[x]=11;break;
    case 'C':
    case 'c':code[x]=12;break;
    case 'D':
    case 'd':code[x]=13;break;
    case 'E':
    case 'e':code[x]=14;break;
    case 'F':
    case 'f':code[x]=15;break;
   }
  }
  for (x=0;x<CODESIZE;x++) tcode[x]=255;
  ShowWindow(hWnd,SW_SHOWMINIMIZED);
  UpdateWindow(hWnd);
  hLib=LoadLibrary("lockdll.dll");
  hfun=GetProcAddress(hLib,"MyHookEr");
  TransitHook=GetProcAddress(hLib,"TransitHook");
  TransitCoor=GetProcAddress(hLib,"TransitCoor");
  prevhook=SetWindowsHook(WH_GETMESSAGE,hfun);
  (*TransitHook)(prevhook);

  lpProc=MakeProcInstance((FARPROC)KeypadBox,hInst);
  DialogBox(hInst,"Keypad",hWnd,lpProc);
  FreeProcInstance(lpProc);

  if (!UnhookWindowsHook(WH_GETMESSAGE,hfun))
   MessageBox(hWnd,"Could not Unhook Message Filter","Combination Lock",MB_OK);
  FreeLibrary(hLib);
  PostQuitMessage(0);

  while(GetMessage(&msg,NULL,NULL,NULL))
  {
   if (TranslateAccelerator(hWnd,hAcc,&msg)==0)
   {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
   }
  }
  return (msg.wParam);
 }
}

long FAR PASCAL WndMainProc(HWND hWnd,
			    unsigned message,
			    WORD wParam,
			    LONG lParam)
{

 switch (message)
 {
  case WM_DESTROY:
   PostQuitMessage(0);
  break;
  case WM_COMMAND:
  default:
  return (DefWindowProc(hWnd,message,wParam,lParam));
 }
 return (NULL);
}

BOOL FAR PASCAL KeypadBox(hDlg,message,wParam,lParam)
HWND hDlg;
unsigned int message;
WORD wParam;
DWORD lParam;
{
 int x,y;
 RECT rect;
 POINT point;

 switch(message)
 {
  case WM_INITDIALOG:
   GetClientRect(hDlg,&rect);
   point.x=rect.left; point.y=rect.top;
   ClientToScreen(hDlg,&point);
   rect.left=point.x; rect.top=point.y;
   point.x=rect.right; point.y=rect.bottom;
   ClientToScreen(hDlg,&point);
   rect.right=point.x; rect.bottom=point.y;
   ClipCursor(&rect);
   SetCursorPos((rect.right-rect.left)/2+rect.left,
		(rect.bottom-rect.top)/2+rect.top);
  return FALSE;
  case WM_COMMAND:
   switch(wParam)
   {
    case 101:case 102:case 103:case 104:
    case 105:case 106:case 107:case 108:
    case 109:case 110:case 111:case 112:
    case 113:case 114:case 115:case 116:
     for (x=0;x<CODESIZE-1;x++) tcode[x]=tcode[x+1];
     tcode[CODESIZE-1]=wParam-100;
     y=0;
     for (x=0;x<CODESIZE;x++) if (tcode[x]==code[x]) y++;
     if (y==CODESIZE)
     {
      ClipCursor(NULL);
      EndDialog(hDlg,1);
     }
    return TRUE;
   }
  return TRUE;
  default:
  return FALSE;
 }
}
