[win32] Console sluit event afvangen in win98

Pagina: 1
Acties:

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Ik probeer mbv inline assembly mijn console programma "close-aware" te maken, dwz, je klikt op het kruisje rechtsboven, en hij sluit netjes af. Volgens MSDN moet je dan het volgende stukje asm uitvoeren:
GAS:
1
2
3
4
5
6
mov ah, 16h    ; Windows multiplex function
mov al, 8Fh    ; VM Close
mov dh, 0      ; Enable or Disable Close Command
mov dl, 01h    ; Enable Close
int 2Fh
mov _AX, ax

Die laatste regel stopt de waarde van register ax in een variabele, zodat ik kan checken of het gelukt is. Dit stukje code zorgt ervoor dat ik verderop met een ander stukje assembler kan checken of er geclosed is. Het probleem is echter dat het ding gruwelijk crashed als ik dit uitvoer. Ik heb het boeltje ook nog eens nagelezen in een interrupt-list, en dit moet goed zijn. Waarom crashed ie hier dan op? Komt het doordat ik het als inline assember uitvoer (__asm{ ... } ) of is er gewoon iets mis met die interrupt aanroep?
Extra info: Compiler=VC, OS=Win98

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23:08
Waar crasht 'ie? Welke signal krijg je?

Als je denkt assembly te kunnen programmeren zonder ooit te hoeven debuggen, dan heb je het mis hoor. ;)

Een klein gokje (bij gebrek aan meer informatie): je moet edx (of nog andere registers) back-uppen?

[ Voor 69% gewijzigd door Soultaker op 04-02-2003 10:57 ]


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Hij crashed bij die int. Het debug-rapport geeft aan dat ax en dx de goede waarde bevatten. Het is een beetje lastig debuggen, want ik develop onder XP en moet het testen onder 98. Deze informatie haal ik dus uit het debug-rapport van Windows. Die zegt verder nog "illegal operation", maar daar haal je ook niet veel uit...
Ik heb al geprobeerd te doen push (e)ax, push (e)dx, en dan weer poppen, maar dat werkt ook niet.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23:08
Werkt het onder XP wel of niet? Zo ja, dan ondersteund Windows 98 het misschien helemaal niet, zo nee, dan kun je daarin beter eerst fixen. Waar heb je deze informatie trouwens vandaan? Microsoft? Staat daar niet wat over Windows versies bij?

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Deze informatie heb ik van MSDN. Het is de bedoeling dat het juist onder Win98 werkt en niet onder Windows XP. Onder XP werkt het close-aware maken op een andere manier (zonder asm, en dat werkt allemaal wel). Het hele idee van interrupts is volgens mij ook uit WinXP gesloopt (en terecht). Dus dat hoef ik niet te proberen...

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Die AH/AL registers geven me te denken. Zijn die interrupts wel beschikbaar in Win32? Win98 kan wel Win16 code draaien, maar dan moet je executable wel als zodanig herkenbaar zijn, en helemaal Win16.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
illegal operation wil zeggen dat in de huidige processor mode je een instructie uitvoert die niet is toegelaten. Is het een puur DOS programma (16Bit?) anders gaat windows die in protected mode draaien en dan kun je maar 1 interrupt aan (33h). Persoonlijk weet ik ook niet wanneer je je Console application kiest in VC wat ie doet maar ik neem aan dat ie 32Bit is. Mischien moet je gaan zoeken in Project Properties om daar 16Bit te vinden (als VC v??? dat tenminste nog kan).

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Ik heb geen idee of het een puur DOS programma is. Ik heb in VC gewoon een console application gestart. Maar ik zal eens kijken of er een optie voor 16-bit is. Maar werkt het dan nog wel onder XP? Ik zou namelijk graag maar 1 executable voor alle OS-en willen hebben...

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
zover ik weet kan XP nog wel pure 16bit-ers draaien zolang die niet aan system resources gaat knabbelen - maar 100% zeker ben ik niet... staat er op MSDN geen help om gewoon 32bits console op Win98 te laten draaien? je kan toch ook in 98 vanuit je console een window maken en aldus te ALT-F4 (close) intercepten zonder een int? Moet het een console zijn BTW? want een gewone window-app (hoeft ook geen visible windows te hebben he - en kan ook schrijven naar cout :)) gaat vast wel werken...

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

SWfreak schreef op 04 February 2003 @ 13:07:
Ik heb geen idee of het een puur DOS programma is. Ik heb in VC gewoon een console application gestart. Maar ik zal eens kijken of er een optie voor 16-bit is. Maar werkt het dan nog wel onder XP? Ik zou namelijk graag maar 1 executable voor alle OS-en willen hebben...


VC kan alleen maar 32 bits console apps bouwen. Dus geen DOS, en geen 16 bits
Wat wil je eigenlijk precies doen? Ik vermoed namelijk dat dat stukje assembler code niet de goede manier is om je doel te bereiken :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Wat ik graag wil is dat onder Win9x mijn console application afsluit als je op het kruisje klikt of als je je computer afsluit. Tot nog toe geeft ie constant een window "This program must close" als je afsluit en dat vind ik erg vervelend. Ik heb heel MSDN afgegraasd op zoek naar hoe ik dit kan doen, en toen kwam ik dus op dat stukje asm. Ik heb werkelijk geen idee hoe ik het anders zou moeten doen. Maar misschien hebben jullie een suggestie.

Een gewone window-app is niet echt de oplossing, omdat ik mijn programma een wrapper is voor weer een ander DOS-programma en dat kan ik niet editen of omzetten. Dus dan krijg ik weer vervelende berichten van dat andere programma.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

kijk eens naar de functie SetConsoleCtrlHandler () :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
.oisyn schreef op 04 February 2003 @ 16:51:
kijk eens naar de functie SetConsoleCtrlHandler () :P
Die heb ik geimplementeerd. Dat was namelijk ook wat ik als eerste probeerde. Het probleem is echter dat ie daar nooit komt! Ik snap niet waarom, maar die wordt gewoon niet aangeroepen onder Win98 bij het afsluiten... Daarom ging ik ook verder zoeken en kwam ik op asm uit. Tenzij ik natuurlijk iets fout doe met mijn controlhandler
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE );
BOOL CtrlHandler( DWORD fdwCtrlType )
{
    switch( fdwCtrlType )
    {
        case CTRL_C_EVENT:
        case CTRL_BREAK_EVENT:
        case CTRL_CLOSE_EVENT:
        case CTRL_LOGOFF_EVENT:
        case CTRL_SHUTDOWN_EVENT:
            //ruim rotzooi op ... en doe dan:
            if( fdwCtrlType == CTRL_LOGOFF_EVENT || fdwCtrlType == CTRL_SHUTDOWN_EVENT )
                return FALSE;
            else
                return TRUE;
        default;
            return FALSE;
    }
}

Maar ik zie niet in wat ik hier verkeerd aan doe.

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
doe je wel een exit? :)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

[quote]The CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals give the process an opportunity to clean up before termination. A HandlerRoutine can perform any necessary cleanup, then take one of the following actions:
  • Call the ExitProcess function to terminate the process.
  • Return FALSE. If none of the registered handler functions returns TRUE, the default handler terminates the process.
  • Return TRUE. In this case, no other handler functions are called, and the system displays a pop-up dialog box that asks the user whether to terminate the process. The system also displays this dialog box if the process does not respond within a certain time-out period (5 seconds for CTRL_CLOSE_EVENT, and 20 seconds for CTRL_LOGOFF_EVENT or CTRL_SHUTDOWN_EVENT).
wat ik hiervan begrijp is dat je na je opruiming idd gewoon een exit () moet doen om het proces af te sluiten (dit is dus wat er gebeurd als alle handlers FALSE retourneren). Aangezien je nu bij een CLOSE TRUE retourneert, krijg je de popup.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
In zekere zin. Ik heb er nog een stukje code inzitten dat wacht totdat het programma waar mijn prog een wrapper om heen is netjes is afgesloten, maar dat heb ik even weggelaten. Verder zou die return FALSE er voor moeten zorgen dat het 'normaal' afgesloten wordt (zie MSDN). Het grote probleem is echter dat ie hier niet eens komt onder Win98! Geen idee hoe dat mogelijk is, maar toch...

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
code:
1
2
3
4
BOOL CtrlHandler( DWORD fdwCtrlType ) 
{
  cout<<"ending"<<flush;
}


dus die "ending" gebeurt nooit?

misschien heb je de callback niet proper geinstalleerd?

op mijn MSDN staat wel niet dat ie de close button doorgeeft... WEL ctrl break etc...

ook:

A process can use the SetProcessShutdownParameters function to prevent the system from displaying the CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT dialog box to the user. In this case, the system terminates the process when HandlerRoutine returns TRUE or when the time-out period elapses

[ Voor 69% gewijzigd door hobbit_be op 04-02-2003 17:22 ]


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Ik krijg die ending nooit als ik de computer afsluit. Wel als ik Control-C indruk, dus de callback zit er goed in (zie ook het stukje code). Ik heb ook geprobeerd om ongeacht de waarde van fdwCtrlType wat te doen, maar ook dat wordt niet aangeroepen...

Ik kijk hier op MSDN http://msdn.microsoft.com...setconsolectrlhandler.asp
en zie daar geen problemen.
SetProcessShutdownParameters is ook een leuke functie, maar zoals je kunt lezen werkt die niet onder Win98.
En er is geen Log off onder Win98... (iig niet op mijn pc)...

[ Voor 40% gewijzigd door SWfreak op 04-02-2003 17:26 ]


  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
doet ie het wel bij een Log-off? (als dat bestaat onder 98 ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

wanneer krijg je de popup nou, bij een close of een shutdown? Of allebei? En wanneer wil je m wel of niet?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Ik krijg bij beide een pop-up (niet dezelfde, maar bij de een zegt ie dat je informatie verliest en bij de andere zegt ie dat het window moet closen). Ik wil in principe geen van beiden zien, maar als dat shutdown-ding me lukt ben ik al blij...

[ Voor 15% gewijzigd door SWfreak op 04-02-2003 18:16 ]


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Ok, ik heb iets gevonden dat het zou moeten doen:
http://cvs.apache.org/vie...c/os/win32/Win9xConHook.c
Van apache geript. Ik kan er alleen geen chocola uit maken. Iemand een idee hoe dit nou precies werkt?

Verwijderd

Bedenk dat als je Apache (GPL) code gebruikt, dat je dan ook je eigen programma GPL moet maken. Zie http://www.gnu.org/copyleft/gpl.html voor meer info.

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
En als ik nou de DLL wil gebruiken waar die functionaliteit in zit, hoe zit het dan precies?
Volgens de license zou ik het moeten kunnen gebruiken, als ik de license maar meeneem. Er staat trouwens ook nergens dat het onder GPL zou vallen :?

[ Voor 48% gewijzigd door SWfreak op 04-02-2003 22:30 ]


Verwijderd

Verwijderd schreef op 04 February 2003 @ 21:45:
Bedenk dat als je Apache (GPL) code gebruikt, dat je dan ook je eigen programma GPL moet maken. Zie http://www.gnu.org/copyleft/gpl.html voor meer info.
Waar lees jij dat Apache GPL code is? Volgens mij staat er toch heel duidelijk "The Apache License"....

  • _js_
  • Registratie: Oktober 2002
  • Laatst online: 13-01 07:19
MS-DOS programma is NIET hetzelfde als een WIN32 CONSOLE programma.

Of je moet een 16 bit dos compiler gebruiken voor je programma, of je blijft VC gebruiken en gebruikt win32 api calls. Het is niet mogelijk dos interrupts te gebruiken in een win32 console programma.

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Goed, ik denk dat ik het probleem heb opgelost door ff goed naar Apache te kijken. Zal er wel ergens een melding in gooien dat ik een idee van hun gebruikt heb.
Het gaat als volgt:
Creeer ergens in de start-up code een nieuwe thread:
C:
1
hCtrlHandlerThread = CreateThread( NULL, 0, &CtrlHandlerThread, NULL, 0, &hCtrlHandlerThreadId );

Deze thread maakt vervolgens een hidden window en gaat naar berichtjes luisteren, specifiek het WM_QUERYENDSESSION en WM_ENDSESSION bericht:
C:
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
46
47
48
49
50
51
DWORD WINAPI CtrlHandlerThread( LPVOID param )
{
    WNDCLASS wc;
    MSG msg;
        HWND hiddenWnd;

    wc.style            = CS_GLOBALCLASS;
    wc.lpfnWndProc      = (WNDPROC) CtrlHandlerWndProc;
    wc.cbClsExtra       = 0;
    wc.cbWndExtra       = 0;
    wc.hInstance        = NULL;
    wc.hIcon            = NULL;
    wc.hCursor          = NULL;
    wc.hbrBackground    = NULL;
    wc.lpszMenuName     = NULL;
    wc.lpszClassName    = "zut";

    RegisterClass( &wc );

    hiddenHwnd = CreateWindow( "zut", "zut", WS_OVERLAPPEDWINDOW & ~WS_VISIBLE, 
             CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, NULL, NULL );

    if( !hiddenHwnd )
        return 1;

    while( GetMessage(&msg, hiddenHwnd, 0, 0) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }

    hiddenHwnd = NULL;

    return 0;
}

LRESULT CALLBACK CtrlHandlerWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    switch( message )
    {
        case WM_CLOSE:
            CtrlHandler( CTRL_CLOSE_EVENT );
            return TRUE;
        case WM_QUERYENDSESSION:
        case WM_ENDSESSION:
            CtrlHandler( CTRL_SHUTDOWN_EVENT );
            return TRUE;
    }

    return DefWindowProc( hwnd, message, wParam, lParam );
}

Hierbij is CtrlHandler een control handler zoals nodig in SetConsoleCtrlHandler. Hierin moet je natuurlijk wat shutdown code plaatsen en je moet ook nog ergens dit hidden window destroyen.
Dat WM_CLOSE bericht staat er wel, maar voor spek en bonen. Als je op het kruisje klikt, wordt helaas geen bericht doorgegeven, maar ja, misschien onder een ander OS dan Win98 weer wel. Ik vind dat niet zo erg, want shutdown was het belangrijkste en dat works like a charm.

Een andere oplossing die ik ergens anders nog kreeg is om een timertje te laten lopen en om de zoveel tijd checken of dat "This program must close window" te zien is. Dan kun je het programma ook netjes afsluiten. Op dit moment is het nadeel dat dit window 100% CPU inneemt en je daardoor eerst shutdown moet cancelen, programma afsluiten en vervolgens weer een nieuwe shutdown doen. Bovenstaande werkt dus duidelijk beter...

Misschien dat een mod dit topic nog even een zinniger titel kan geven, het ging tenslotte meer om het shutdown probleem dan om die asm boel...

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
zoals ik dus vermoed had maak je dus een 'invisible' window :) dat met dat timertje kun je dan ook weer in een thread gooien met een sleep :)...

van die license zou ik me geen BAL aantrekken - deze code is zo uniform dat dat belachelijk zou zijn. en als ik mezelf mag quoten:
je kan toch ook in 98 vanuit je console een window maken en aldus te ALT-F4 (close) intercepten zonder een int? Moet het een console zijn BTW? want een gewone window-app (hoeft ook geen visible windows te hebben he - en kan ook schrijven naar cout ) gaat vast wel werken...
dus heb je idee van mij , heb je het zelf geimplementeerd en ik heb GEEN bloody license. BTW deze code zit vast ook in GLUT of eender welk console met window programma....

[ Voor 84% gewijzigd door hobbit_be op 05-02-2003 15:20 ]


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
Okok, ik gooi hem eruit :)

Is trouwens wel grappig. Heb ik de boel net gefixt onder Win98. En wat blijkt: het werkt niet onder WinXP. Hij roept daar ook die console handler niet aan. En die window oplossing gaat daar ook niet op. Ik begrijp er zolangzamerhand steeds minder van. Leuk die events als CTRL_SHUTDOWN_EVENT, maar als die toch niet worden verzonden, wat heb je er dan aan?

Iemand nog leuke ideeen voor XP?

Verwijderd

hobbit_be schreef op 05 februari 2003 @ 15:15:
van die license zou ik me geen BAL aantrekken - deze code is zo uniform dat dat belachelijk zou zijn. en als ik mezelf mag quoten:
Dat boeit AB_SO_LUUT niet. De code is gejat en valt dus onder de betreffende licentie.

  • SWfreak
  • Registratie: Juni 2001
  • Niet online
De code is niet gejat, maar zelf geschreven (ik kijk namelijk wel uit om te copy-pasten). Er is geen manier waarop je de code uit apache kan vergelijken met de code van mij. Dat kan je zelf nagaan als je wil....
Ik zal nog eens nagaan in hoeverre het dan nog onder de licentie valt, maar volgens mij geldt die dan niet meer. Het is namelijk geen modification ofzo. Het is gewoon het idee (zoals ook al door hobbit_be naar voren gebracht) en dat heb ik zelf ingeklopt. Dan zou het idee gepatenteerd moeten zijn om credit te moeten geven, en dat is het volgens mij niet. Ik denk dat als ik mijn huidige lijntje laat staan
This program includes an idea developed by the Apache
Software Foundation (http://www.apache.org).
Although I coded it myself, the idea how to do it was theirs.
dat ik dan genoeg doe. Maar ik zal er eens een wetboek op naslaan. :)

[ Voor 62% gewijzigd door SWfreak op 05-02-2003 20:19 ]


  • SWfreak
  • Registratie: Juni 2001
  • Niet online
* SWfreak doet nog maar eens een schopje naar boven :)
Iemand een idee hoe je onder Windows (XP/2000) een console app laat detecteren dat de gebruiker Windows wil afsluiten?

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 23:08
Windows stuurt applicaties netjes WM_QUERYENDSESSION en WM_ENDSESSION messages, als de gebruiker (of een andere applicatie) het systeem wil afsluiten (respectievelijk gaat afsluiten).

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21:34

.oisyn

Moderator Devschuur®

Demotivational Speaker

even de titel gewijzigd, deze dekt de lading beter :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1