[Win32/Labwindows/CVI] keyboardhook en GINA werkt niet samen

Pagina: 1
Acties:

  • decipherer
  • Registratie: Februari 2002
  • Laatst online: 02:37
Programmeeromgeving applicatie: Labwindows/CVI (6.0)
Programmeeromgeving GINA dll: ms visual c++ 6.0

Voor een applicatie die eigenlijk de gebruikersinterface van een ovenbesturing is wil ik graag voorkomen dat gebruikers dingen doen die ze eigenlijk niet mogen (de applicatie draait o.a. in een fabriek in China waar de operators van de ovens 's nachts spelletjes gaan spelen of schijnbaar willekeurig op knoppen drukken).

Dit wil ik bereiken door:
1) De muis af te vangen zodat deze niet buiten de applicatie kan komen (geen probleem).
2) Het toetsenbord af te vangen zodat men geen invoer kan geven en niet mbv alt-tab van applicatie kan wisselen (probleem!)
3) verschillende menu-items in de applicatie uit te zetten zodat gebruikers er geen gebruik van kunnen maken (geen probleem).

Operators met voldoende bevoegdheid kunnen deze locks uitschakelen door een menu item te kiezen waarna een wachtwoord veld verschijnt. Na het invoeren van het juiste wachtwoord worden alle beperkingen opgeheven.

Het afvangen van het toetsenbord geeft me problemen. Om dit te bereiken heb ik een low level keyboard hook geplaatst. In de functie die deze hook uitvoert check ik of het wachtwoord invoer veld actief en en zo ja laat ik bepaalde toetsaanslagen door (Labwindows/CVI code):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**************************************************************
function: SetKeyboardHook
goal:     Set low level windows hook for keyboard
returns:  The hook, which is non-zero on succes
**************************************************************/
HHOOK SetKeyboardHook(void) {
   HINSTANCE instanceHandle = GetModuleHandle(NULL);

   // Set Low Level keyboard hook
   if (!keyboardHook)
      keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyboardHookFunction, instanceHandle, 0);

   // Set Mutex which allows GINA DLL to verify that the keyboard hook has been set.
   if (!keyboardMutex) 
      keyboardMutex = CreateMutex (NULL, TRUE, "CVI_KEYBOARD_HOOK_SET_");

   return keyboardHook;
}


/**************************************************************
function: KeyboardHookFunction
goal:     This is the function that get's called for every keyboard event by every application when the keyboard hook is active
returns:  zero to let other applications process key strokes. Non-zero otherwise
**************************************************************/
LRESULT CALLBACK KeyboardHookFunction(int code, WPARAM wParam, LPARAM lParam) {
   KBDLLHOOKSTRUCT *keyboarddata;
   HWND hWnd;
   
   if (code < 0)
      CallNextHookEx(NULL, code, wParam, lParam);
      
   // certain keys may be used when password control on keyboard access panel has focus
   if ((GetActivePanel() == keyboardAccessPanel) && (GetActiveCtrl(keyboardAccessPanel) == keyboardAccessPasswordCtrl)) {
      keyboarddata = (KBDLLHOOKSTRUCT *)lParam;                             // get keyboard information (keyboarddata->vkCode is ASCII value of pressed key)
      if (((keyboarddata->vkCode >= 48) && (keyboarddata->vkCode <= 57)) || // if pressed key is a number (0-9)
          ((keyboarddata->vkCode >= 97) && (keyboarddata->vkCode <= 122))|| // if pressed key is a letter (a-z)
          ((keyboarddata->vkCode >= 65) && (keyboarddata->vkCode <= 90)) || // if pressed key is capital letter (A-Z)
          (keyboarddata->vkCode == 8) || (keyboarddata->vkCode == 13) || (keyboarddata->vkCode == 10))      // if pressed key is backspace or enter
             return 0;
   }
      
   Beep();
   return 1; // return non-zero value if other applications may not process key strokes   
}

Zoals je ziet geeft deze functie een geluidssignal wanneer een toets ingedrukt is die geblokkeerd is.
Met de low level hook kan ik alle toetsen afvangen, behalve ctrl-alt-del. Om die af te vangen heb ik een nieuwe GINA geplaatst (gebaseerd op het ginastub voorbeeld uit msdn). In die GINA voorkom ik dat er iets gebeurd wanneer op ctrl-alt-del gedrukt wordt en de applicatie gelockt is (msvc++ code):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* This function is adjusted to lock ctrl-alt-del */
int
WINAPI
WlxLoggedOnSAS(
    PVOID           pWlxContext,
    DWORD           dwSasType,
    PVOID           pReserved)
{

    HANDLE keyboardMutex;

    if (dwSasType == WLX_SAS_TYPE_CTRL_ALT_DEL) // catch ctrl-alt-delete
    {
        /* Check for mutex */
        keyboardMutex = OpenMutex (MUTEX_ALL_ACCESS, FALSE, "CVI_KEYBOARD_HOOK_SET_");
        if (keyboardMutex != NULL) {
            CloseHandle(keyboardMutex);
            return WLX_SAS_ACTION_NONE; // lock ctrl-alt-delete if mutex exists
        }
    }
    
    return GWlxLoggedOnSAS( pWlxContext, dwSasType, pReserved );
}

Het probleem:
Als, terwijl de applicatie gelockt is, er op ctrl-alt-del gedrukt wordt is het daarna niet meer mogelijk om een wachtwoord in te voeren, het sterretje verschijnt stomweg niet in het invoer veld.
Er wordt een geluidssignaal gegeven bij geblokkeerde toetsen en niet bij gedeblokkeerde toetsen, de code (KeyboardHookFunction) herkent de toetsaanslag dus wel goed.
Ik heb al geprobeerd om de hooks opnieuw te plaatsen voordat het wachtwoord scherm getoond wordt, maar dit mocht niet baten.
Ook dacht ik dat de applicatie misschien niet echt actief stond, maar het expliciet actief maken van het window hielp ook niet.

Ondertussen weet ik niet meer zo goed waar ik het nog moet zoeken en ik hoop dat iemand me erbij kan helpen :)

[ Voor 11% gewijzigd door decipherer op 12-05-2006 11:00 ]

De beste ideeën komen als je bezig bent.


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Omdat je nog steeds beep() hoort, kan je er vanuit gaan dat de hooks dus nog wel goed zitten.
Verder vind ik je mutex gedoe wat vaag (zet je de return code van CreateMutex in een global var, en na de CloseHandle wordt deze toch compleet verwijderd omdat die de enige handle was?) maar daar ben ik dan ook niet zo bekend mee :P

Dus, in kort, KeyboardHookFunction wordt aangeroepen, en de volgende if failt:
code:
1
2
if ((GetActivePanel() == keyboardAccessPanel) && 
    (GetActiveCtrl(keyboardAccessPanel) == keyboardAccessPasswordCtrl)) {

Vraag me niet de waarom, want GetActivePanel & GetActiveCtrl kan ik niet op msdn vinden, en de variabelen hierin zijn me ook onbekend. :)

Spolap: Interactive webcomic


  • decipherer
  • Registratie: Februari 2002
  • Laatst online: 02:37
In mijn applicatie maak ik een mutex aan op het moment dat ik deze wil locken. De GINA kijkt bij elke ctrl-alt-del of deze mutex aanwezig is, zo ja wordt ctrl-alt-del geblokkeerd, anders wordt deze gewoon doorgelaten en verschijnt bv taskmanager.

Ik hoor een beep als ik buiten het wachtwoord invoerveld op het toetsenbord druk, of als ik op een 'foute' toets druk. Als ik voorheen een keer ctrl-alt-del gedrukt heb, de applicatie gelocked is en de cursor op het wachtwoord invoerveld staat hoor ik echter geen beep, terwijl er geen sterretje verschijnt. Het if-statement dat je aangeeft is dus true op dat moment (geen beep immers)

De functies die niet op msdn staan zijn functies uit een library van Labwindows/CVi en controleren of het wachtwoord invoerschermpje en daarin het wachtwoord invoerveld actief zijn.

[ Voor 12% gewijzigd door decipherer op 12-05-2006 13:27 ]

De beste ideeën komen als je bezig bent.


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

In dat geval, return je niet te vroeg?
Check het voorbeeld op http://msdn.microsoft.com...wing/hooks/usinghooks.asp

Ipv return 0 na die if zal je waarschijnlijk CallNextHookEx willen doen, zodat de toetsen welke je checked doorgegeven worden. Dus:
C:
1
2
3
4
5
6
7
8
//oud:
if ( ... )
  return 0;

//nieuw:
if ( ... )
  // De NULL hier gok ik even, het msdn voorbeeld geeft hier wel data door
  return CallNextHookEx(NULL, code, wParam, lParam);

[ Voor 5% gewijzigd door wacco op 13-05-2006 18:17 . Reden: lompe typo.. ]

Spolap: Interactive webcomic


  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

waarom zet je geen policy op die PC's zodat sommige acties niet kunnen ?

imo veel eenvoudiger dan dit...

ASSUME makes an ASS out of U and ME


  • decipherer
  • Registratie: Februari 2002
  • Laatst online: 02:37
Na nog wat debuggen ben ik eruit. Ik weet niet waarom maar blijkbaar moet je de ctrl (vkCode = 162 en 163) altijd door laten gaan (dus 0 voor teruggeven) in de hook functie. De volgende code werkt wel namelijk:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**************************************************************
function: KeyboardHookFunction
goal:     This is the function that get's called for every keyboard event by every application when the keyboard hook is active
returns:  zero to let other applications process key strokes. Non-zero otherwise
**************************************************************/
LRESULT CALLBACK KeyboardHookFunction(int code, WPARAM wParam, LPARAM lParam) {
   KBDLLHOOKSTRUCT *keyboarddata;
   HWND hWnd;
   
   if (code < 0)
      return CallNextHookEx(NULL, code, wParam, lParam);

   keyboarddata = (KBDLLHOOKSTRUCT *)lParam;  // get keyboard information
   
   // always return 0 for ctrl, otherwise we are locked in after ctrl-alt-del...
   if ((keyboarddata->vkCode == 162) || (keyboarddata->vkCode == 163))
      return 0;

   // certain keys may be used when password control on keyboard access panel has focus
   if ((GetActivePanel() == keyboardAccessPanel) && (GetActiveCtrl(keyboardAccessPanel) == keyboardAccessPasswordCtrl)) {
      if (((keyboarddata->vkCode >= 48) && (keyboarddata->vkCode <= 57)) || // if pressed key is a number (0-9)
          ((keyboarddata->vkCode >= 97) && (keyboarddata->vkCode <= 122))|| // if pressed key is a letter (a-z)
          ((keyboarddata->vkCode >= 65) && (keyboarddata->vkCode <= 90)) || // if pressed key is capital letter (A-Z)
          (keyboarddata->vkCode == 8) || (keyboarddata->vkCode == 13) || (keyboarddata->vkCode == 10))   // if pressed key is backspace or enter
             return 0;
   }
   
   Beep();
   return 1; // return non-zero value if other applications may not process key strokes
}


Mocht iemand meer informatie hebben over waarom het nodig is deze door te geven dan hoor ik dat graag :)

edit:
Ook de rechtse ctrl-button doorlaten..

[ Voor 10% gewijzigd door decipherer op 15-05-2006 11:40 ]

De beste ideeën komen als je bezig bent.


  • The End
  • Registratie: Maart 2000
  • Laatst online: 21-02 19:22

The End

!Beginning

Je hebt het over PC's in China. Weet je zeker dat die code daarop werkt? Als ze daar een chinese versie van Windows hebben, dan heb je redelijke kans dat je nu niet de goede (of iig alle) toetsen afvangt.

  • decipherer
  • Registratie: Februari 2002
  • Laatst online: 02:37
Daar heb je wel een goed punt. De pc's die gebruikt worden voor de oven aansturing zijn echter allemaal voorzien van een engelstalige versie van windows.

Toen ik zelf eens in china was zag ik trouwens dat ze gewoon een qwerty toetsenbord gebruiken waar enkele chinese karakters boven de toetsen staan die ze mbv alt-gr kunnen gebruiken. Ook kunnen ze volgens mij karakters maken door enkele letters te typen en die vervolgens samen te voegen tot een chinees karakter.

De beste ideeën komen als je bezig bent.

Pagina: 1