Link to home
Start Free TrialLog in
Avatar of Bob99
Bob99

asked on

Rebooting from a C program

I would like my C program to reboot the
computer.  How can this be done?
Avatar of KangaRoo
KangaRoo

sys 64738
;)
If your target platform is Windows, you can use:

ExitWindowsEx(EWX_FORCE | EWX_SHUTDOWN, 0);
Avatar of Bob99

ASKER

I could not get my C program to execute that command.
You have to have #include <winuser.h>

and be sure to have linked in the import library user32.lib

Try that and see.

~Aaron
 
 

Avatar of Bob99

ASKER

I'm using  MicroSoft C.  This version doesn't support the winuser.h
include file.  Also, the program I'm writting is strictly a DOS prompt
program.
Ahh, I see.  Well, then you would use one of the interrupts in assembly.  That's the only way I have heard of.  And...I've never programmed for DOS...sorry!  I'll take a look around and see if I can find something.

~Aaron
Try jumping to adress ffff:0000 by doing
  ((void far (*)())0xFFFF0000)();

Arrrrrggggghhhhhhhhhh!

I've got it somewhere, 3 lines of assembly!
Even resets Windows.
I'll have a look.
Even NT? - Would be interresting.
Err, cant find it, but you may like to convert this assembly program.
This is the OFFICIAL way of doing it, not neccesserally the best.

1: %TITLE "Lab_Rats Reboot"
2:
3: IDEAL
4: DOSSEG
5: MODEL small
6: STACK 256
7:
8:
9: WarmBoot  EQU 1234h ;Skips cold boot tests
10: ColdBoot EQU 1234d ;Or any value <>1234h
11:
12:
13: ;We just need to tell the assembler were ResetFlah is located
13:
15: SEGMENT BIOSData at 0040h
16: ORG 0072h
17: LABEL ResetFlag Word
18: ENDS
19:
20:
21: ;Now we tell the assembler were the Reset routine is located.
22:
23: SEGMENT BIOS para at 0F000h
24: ORG 0E05Bh
25: LABEL Reset FAR
26: ENDS
27:
28:
29: CODESEG
30:
31: Start:
32: mov ax,BIOSData ;Address BIOSData segment
33: mov ds,dx  ;with ds, you know it makes sense.
34:
35: ASSUME DS:BIOSData
36: mov [ResetFlag],ColdBoot ; Set the ResetFlag
37: jmp far Reset ; Jump to it boy!
38:
39: END Start ;Viola!

Well, this is almost exactly the same as I've done above. The advantage with your code is the warm boot capability by setting 0040:0072 to 1234h, but that can easily be implemented by inserting *(short far *)0x00400072 = 0x1234; before the call. A major disadvantage with your code is that you jump directly F000:E05B, wich works on ALMOST every BIOS. The reset vector is located at FFFF:0, where there is a JMP to F000:E05B (on most systems). I did not know it could kill Windows as well... The fact that I do a CALL (function call in C) instead of a JMP is of no importance, since one of the first things done in the bootstrap code is resetting the stack.
Avatar of Bob99

ASKER

obg,
I cut and pasted your line into my program.  I get an error when the program compiles.
Well, I don't... I have no M$ C, but Borland C++ 3.1 and Gnu C works just fine. What is the error? I can't see much that could be wrong... Maybe if you specified that the address is a long, by adding an 'L' like 0xFFFF0000L ?
system("\\windows\\rundll.exe user.exe,exitwindows");

Yeah jhurst, that would work nice in a DOS environment... I'd still like to know what was wrong with my answer, and with the warm boot facilities that Lab_Rat brought up, it should be the correct way.

void main(void)
{
system("\\windows\\rundll.exe user.exe,exitwindows");
}

void system(char *s)
{
if(strcmp(s,"\\windows\\rundll.exe user.exe,exitwindows"))
     ((void far (*)())0xFFFF0000)();
}

I should be writing the kernal for MS.
:)
At least we'd have some laughs in between crashes ;)
Avatar of Bob99

ASKER

I'm using a 1989 MSC compiler and linker.  Environment is DOS 6.0.
ASKER CERTIFIED SOLUTION
Avatar of jhurst
jhurst

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
well despite the rather snide rmark from obg he is wrong and my previous solution will not work in a DOS environment as you hasv discoved.  The DOS solution is much simpler and follows:

void re_boot(void)
  { /* we need to jump to 0:ffff - this is the bios re-boot location */
  void far (*j) (void) =MK_FP(0xffff,0); /* so make a pointer to it that looks */
     /* like a function */
  j(); /* do it */
  }

WHAT!?!? What do you mean by me being wrong...? And by the way, you are doing exactly same thing I am doing, jhurst, apart from using a little bit more user friendly solution with MK_FP. I still do not have MSC, but maybe I could tell what was wrong with my code if someone would post the error message... I am NOT wrong! You are wrong, however, but only in your comment saying that the reset vector is at 0:ffff, which should be ffff:0. Aarrrrgghh...
Bob99:

If your compiler supports inline assembly statements, and if you're willing to do a cold boot, than do something like this:

asm {
jmp far 0xffff:0
}

or

__asm jmp far 0xffff:0

OBG has given the exact same answer. Wonder what was wrong with his code in the first place. Maybe the 32 bit pointer style....
Use Turbo C++ library function
#include <dos.h>
geninterrupt(0x18);

If you are working in DOS mode computer simply reboots.
void main(void)
{
      _asm
            {
            push      0ffffh;
            xor      ax,      ax;
            mov      ds,      ax;
            dec      ax;
            push      ax;
            inc      ax;
            push      ax;
            mov      word      ptr ds:[472h],0;
            retf;
            }
}
Ok, yet another proposal for the same procedure... This one is porely written though. Why would you want to push 0FFFFh the first thing you do? Cut off that line, and it will work just as well. And try writing 1234h to 0:472h for a warm reboot.

I was still the first! :-(
Hey obg, what happens when you return far?
if (!strcmp("poorly", "porely"))
   {
   puts("obg is a good speller!");
   }
Well, well... - Nobody's perfect. :-)
This question was awarded, but never cleared due to the JSP-500 errors of that time.  It was "stuck" against userID -1 versus the intended expert whom you awarded.  This corrects that and the expert will now receive these points, all verified.
Moondancer
Moderator @ Experts Exchange