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 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