92 lines
2.4 KiB
C
92 lines
2.4 KiB
C
/* ----------------------------------------------------------------------- *
|
|
*
|
|
* Copyright 2013 Sebastian Herbszt - All Rights Reserved
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
* Boston MA 02110-1301, USA; either version 2 of the License, or
|
|
* (at your option) any later version; incorporated herein by reference.
|
|
*
|
|
* ----------------------------------------------------------------------- */
|
|
|
|
/*
|
|
* poweroff.c
|
|
*
|
|
* APM poweroff module
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <com32.h>
|
|
|
|
int main(int argc __unused, char *argv[] __unused)
|
|
{
|
|
com32sys_t inregs, outregs;
|
|
|
|
memset(&inregs, 0, sizeof inregs);
|
|
|
|
inregs.eax.l = 0x5300; /* APM Installation Check (00h) */
|
|
inregs.ebx.l = 0; /* APM BIOS (0000h) */
|
|
__intcall(0x15, &inregs, &outregs);
|
|
|
|
if (outregs.eflags.l & EFLAGS_CF) {
|
|
printf("APM not present.\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((outregs.ebx.l & 0xffff) != 0x504d) { /* signature 'PM' */
|
|
printf("APM not present.\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((outregs.eax.l & 0xffff) < 0x101) { /* Need version 1.1+ */
|
|
printf("APM 1.1+ not supported.\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((outregs.ecx.l & 0x8) == 0x8) { /* bit 3 APM BIOS Power Management disabled */
|
|
printf("Power management disabled.\n");
|
|
return 1;
|
|
}
|
|
|
|
memset(&inregs, 0, sizeof inregs);
|
|
inregs.eax.l = 0x5301; /* APM Real Mode Interface Connect (01h) */
|
|
inregs.ebx.l = 0; /* APM BIOS (0000h) */
|
|
__intcall(0x15, &inregs, &outregs);
|
|
|
|
if (outregs.eflags.l & EFLAGS_CF) {
|
|
printf("APM RM interface connect failed.\n");
|
|
return 1;
|
|
}
|
|
|
|
memset(&inregs, 0, sizeof inregs);
|
|
inregs.eax.l = 0x530e; /* APM Driver Version (0Eh) */
|
|
inregs.ebx.l = 0; /* APM BIOS (0000h) */
|
|
inregs.ecx.l = 0x101; /* APM Driver version 1.1 */
|
|
__intcall(0x15, &inregs, &outregs);
|
|
|
|
if (outregs.eflags.l & EFLAGS_CF) {
|
|
printf("APM 1.1+ not supported.\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((outregs.ecx.l & 0xffff) < 0x101) { /* APM Connection version */
|
|
printf("APM 1.1+ not supported.\n");
|
|
return 1;
|
|
}
|
|
|
|
memset(&inregs, 0, sizeof inregs);
|
|
inregs.eax.l = 0x5307; /* Set Power State (07h) */
|
|
inregs.ebx.l = 1; /* All devices power managed by the APM BIOS */
|
|
inregs.ecx.l = 3; /* Power state off */
|
|
__intcall(0x15, &inregs, &outregs);
|
|
|
|
if (outregs.eflags.l & EFLAGS_CF) {
|
|
printf("Power off failed.\n");
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|