• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ----------------------------------------------------------------------- *
2  *
3  *   Copyright 2013 Sebastian Herbszt - All Rights Reserved
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
8  *   Boston MA 02110-1301, USA; either version 2 of the License, or
9  *   (at your option) any later version; incorporated herein by reference.
10  *
11  * ----------------------------------------------------------------------- */
12 
13 /*
14  * poweroff.c
15  *
16  * APM poweroff module
17  */
18 
19 #include <stdio.h>
20 #include <string.h>
21 #include <com32.h>
22 
main(int argc __unused,char * argv[]__unused)23 int main(int argc __unused, char *argv[] __unused)
24 {
25 	com32sys_t inregs, outregs;
26 
27 	memset(&inregs, 0, sizeof inregs);
28 
29 	inregs.eax.l = 0x5300; /* APM Installation Check (00h) */
30 	inregs.ebx.l = 0; /* APM BIOS (0000h) */
31 	__intcall(0x15, &inregs, &outregs);
32 
33 	if (outregs.eflags.l & EFLAGS_CF) {
34 		printf("APM not present.\n");
35 		return 1;
36 	}
37 
38 	if ((outregs.ebx.l & 0xffff) != 0x504d) { /* signature 'PM' */
39 		printf("APM not present.\n");
40 		return 1;
41 	}
42 
43 	if ((outregs.eax.l & 0xffff) < 0x101) { /* Need version 1.1+ */
44 		printf("APM 1.1+ not supported.\n");
45 		return 1;
46 	}
47 
48 	if ((outregs.ecx.l & 0x8) == 0x8) { /* bit 3 APM BIOS Power Management disabled */
49 		printf("Power management disabled.\n");
50 		return 1;
51 	}
52 
53 	memset(&inregs, 0, sizeof inregs);
54 	inregs.eax.l = 0x5301; /* APM Real Mode Interface Connect (01h) */
55 	inregs.ebx.l = 0; /* APM BIOS (0000h) */
56 	__intcall(0x15, &inregs, &outregs);
57 
58 	if (outregs.eflags.l & EFLAGS_CF) {
59 		printf("APM RM interface connect failed.\n");
60 		return 1;
61 	}
62 
63 	memset(&inregs, 0, sizeof inregs);
64 	inregs.eax.l = 0x530e; /* APM Driver Version (0Eh) */
65 	inregs.ebx.l = 0; /* APM BIOS (0000h) */
66 	inregs.ecx.l = 0x101; /* APM Driver version 1.1 */
67 	__intcall(0x15, &inregs, &outregs);
68 
69 	if (outregs.eflags.l & EFLAGS_CF) {
70 		printf("APM 1.1+ not supported.\n");
71 		return 1;
72 	}
73 
74 	if ((outregs.ecx.l & 0xffff) < 0x101) { /* APM Connection version */
75 		printf("APM 1.1+ not supported.\n");
76 		return 1;
77 	}
78 
79 	memset(&inregs, 0, sizeof inregs);
80 	inregs.eax.l = 0x5307; /* Set Power State (07h) */
81 	inregs.ebx.l = 1; /* All devices power managed by the APM BIOS */
82 	inregs.ecx.l = 3; /* Power state off */
83 	__intcall(0x15, &inregs, &outregs);
84 
85 	if (outregs.eflags.l & EFLAGS_CF) {
86 		printf("Power off failed.\n");
87 		return 1;
88 	}
89 
90 	return 0;
91 }
92