C get battery life under Windows 7 - c

I'm trying to code a program that gets the % of a laptop battery and then displays a CMD showing a message (for example: 10% -> "Low battery!").
I've tried to google it, and it seems they all tried with C++ or C#.
Can anybody help me with C, please?
Edit: thanks zakinster for your reply. Shouldn't it look something like this? This code ain't working.
#include <Windows.h>
#include <Winbase.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
SYSTEM_POWER_STATUS status;
GetSystemPowerStatus(&status);
unsigned char battery = status.BatteryLifePercent;
printf("%s", battery);
}

GetSystemPowerStatus from the Win32 API should provide the information you need :
SYSTEM_POWER_STATUS status;
if(GetSystemPowerStatus(&status)) {
unsigned char battery = status.BatteryLifePercent;
/* battery := 0..100 or 255 if unknown */
if(battery == 255) {
printf("Battery level unknown !");
}
else {
printf("Battery level : %u%%.", battery);
}
}
else {
printf("Cannot get the power status, error %lu", GetLastError());
}
See the documentation of the SYSTEM_POWER_STATUS structure for a complete list of contained information.

Related

Make Xorg recognize libevdev virtual device

I've been trying to create a simple program using libevdev to make a virtual device that will simply move the mouse by 50 points on the X axis every second. The program runs just fine, however Xorg won't recognize the newly created virtual device.
I suppose it's going to be something trivial, but I cannot figure out what.
Xorgs' logs say:
[ 5860.310] (II) config/udev: Adding input device test device Mouse (/dev/input/event18)
[ 5860.310] (II) No input driver specified, ignoring this device.
[ 5860.310] (II) This device may have been added with another device file.
The program:
#include <libevdev/libevdev.h>
#include <libevdev/libevdev-uinput.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static void check(int i) {
if (i < 0) {
printf("%s\n", strerror(-i));
exit(1);
}
}
int main() {
struct libevdev* evdev = libevdev_new();
libevdev_set_name(evdev, "test device Mouse");
libevdev_set_id_vendor(evdev, 0x1);
libevdev_set_id_product(evdev, 0x1);
libevdev_set_id_version(evdev, 0x1);
libevdev_set_id_bustype(evdev, BUS_USB);
check(libevdev_enable_event_type(evdev, EV_REL));
check(libevdev_enable_event_code(evdev, EV_REL, REL_X, NULL));
check(libevdev_enable_event_code(evdev, EV_REL, REL_Y, NULL));
check(libevdev_enable_event_code(evdev, EV_SYN, SYN_REPORT, NULL));
struct libevdev_uinput* uinput;
check(libevdev_uinput_create_from_device(evdev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uinput));
for (int i = 0; i < 1000; i++) {
check(libevdev_uinput_write_event(uinput, EV_REL, REL_X, 50));
check(libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0));
sleep(1);
}
}
What am I doing wrong?
The issue was that mouse buttons need to be enabled for mouse movements to work.
Adding these lines fixes the issue:
check(libevdev_enable_event_type(evdev, EV_KEY));
check(libevdev_enable_event_code(evdev, EV_KEY, BTN_LEFT, NULL));
check(libevdev_enable_event_code(evdev, EV_KEY, BTN_RIGHT, NULL));

Unicode symbols

I wrote the following code to generate Unicode symbols for card suits in C. It works fine and I don't need to change the font family or the code page of the console (I use Windows 10 and Dev-C++) but it seems that I can generate only those symbols. Indeed, if I try other values to generate other symbols, like for chess, dice, domino or others as shown here unicode symbols for games, that code does not work. Why? Thank you in advance for your help.
#include <stdio.h>
#include <fcntl.h>
#define SPADE L"\u2660"
#define CLUB L"\u2663"
#define HEART L"\u2665"
#define DIAMOND L"\u2666"
enum SUIT {spade = 1, club, heart, diamond};
void printSuit(int suitToSelect) {
_setmode(_fileno(stdout), _O_U16TEXT);
switch (suitToSelect) {
case spade:
wprintf(SPADE);
break;
case club:
wprintf(CLUB);
break;
case heart:
wprintf(HEART);
break;
case diamond:
wprintf(DIAMOND);
break;
}
_setmode(_fileno(stdout), _O_TEXT);
}
int main(void)
{
printSuit(spade);
printSuit(heart);
printSuit(club);
printSuit(diamond);
printf("\n");
printf("Normal text\n");
return 0;
}
the code below works fine with Dev-C++ and Windows 10.
You can see the nice result in the screenshot of the console.
You can select different fonts in the code
to visualize unicode symbols; each font family
prints the symbols in different styles. Try it!
I hope that this answer can help somebody
who had my problem.
Thank you.
#include <windows.h>
#include <stdio.h>
int main(void)
{
CONSOLE_FONT_INFOEX cfi;
cfi.cbSize = sizeof cfi;
cfi.nFont = 0;
cfi.dwFontSize.X = 20;
cfi.dwFontSize.Y = 40;
cfi.FontFamily = FF_DONTCARE;
cfi.FontWeight = FW_NORMAL;
wcscpy(cfi.FaceName, L"Dejavu Sans Mono");
//wcscpy(cfi.FaceName, L"MS Gothic");
//wcscpy(cfi.FaceName, L"MS Mincho");
//wcscpy(cfi.FaceName, L"NSimSun");
SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi);
SetConsoleOutputCP(65001);
printf("\u2660 \u2661 \u2662 \u2663 \u2664 \u2665 \u2666 \u2667 \n");
printf("\u265B \u265C \u265D \u265E\n");
printf("\u265F \u265A \u2655 \u2656 \u2657\n");
printf("\u2658 \u2659 \u2654 \n");
printf("\u2680 \u2681 \u2682 \u2683 \u2684 \u2685\n");
printf("\u2554 \u2555 \u2556 \u2563 \u255A \u255B \u255C \u255D\n");
return 0;
}

Problem getting full version number for Windows 10 with GetFileVersionInfo and VerQueryValue

I want to get the full version number for Windows, just like CMD does:
I ended up with this MS doc that says:
To obtain the full version number for the operating system, call the
GetFileVersionInfo function on one of the system DLLs, such as
Kernel32.dll, then call VerQueryValue to obtain the
\StringFileInfo\\ProductVersion subblock of the file version
information.
So I tried to use those functions with this code:
#include <Windows.h>
#include <wchar.h>
#pragma comment(lib, "Mincore.lib")
int wmain(int argc, wchar_t* argv[])
{
// GetFileVersionInfoW
LPCWSTR fileName = L"C:\\Windows\\System32\\kernel32.dll";
DWORD fileInfoSize;
fileInfoSize = GetFileVersionInfoSizeW(fileName, NULL);
if (fileInfoSize == 0)
{
fwprintf(stderr, L"\nError code: %u\n", GetLastError());
return;
}
// GetFileVersionInfoW
VOID* pFileVerInfo = malloc(fileInfoSize);
if (pFileVerInfo == NULL)
{
fwprintf(stderr, L"Failed allocating!\n");
return;
}
if (!GetFileVersionInfoW(fileName, 0, fileInfoSize, pFileVerInfo))
{
fwprintf(stderr, L"Error code: %u\n", GetLastError());
free(pFileVerInfo);
return;
}
// VerQueryValueW
LPCWSTR subBlock = L"\\StringFileInfo\\\\ProductVersion";
VS_FIXEDFILEINFO * pFileInfo;
UINT pLen = 0;
if (!VerQueryValueW(pFileVerInfo, subBlock, (LPVOID*)& pFileInfo, &pLen))
{
fwprintf(stderr, L"Error code: %u\n", GetLastError());
return;
}
return 0;
}
However, the VerQueryValueW function fails with code 1813 and I have no idea why. I also have no idea how I can show the full version after calling the function.
Can you help me?
L"\\StringFileInfo\\\\ProductVersion" is not correct. There must be a Language ID in the middle. On my Windows 10 installation, a working string is: L"\\StringFileInfo\\040904B0\\ProductVersion". But maybe this would differ on other systems.
As suggested by Jonathan Potter in comments, you could find the ID by querying \\VarFileInfo\\Translation.
Simpler options to achieve the goal include:
Query VS_FIXEDFILEINFO instead of StringFileInfo
Read the OS version from the Windows API instead of querying a random DLL.

The Kernel starts behaving abnormally when the kernel code gets a little bigger

I am developing an OS kernel. I am facing a problem that till a particular size of the kernel - 8KB it runs perfectly but as it gets just a little over 8KB, it starts behaving abnormally. The clear screen function doesn't work, the scrolling function doesn't work etc.
I am using the bochs emulator with a 1.44MB floppy configuration.
My code working correctly is -
#include "functions.h"
#include "stdint.h"
#include "stddef.h"
#include "../drivers/colors.h"
void delay();
char getScancode();
void main()
{
/*Declarations*/
char* str = "Welcome to MyOS v0.2.4 By Anish Sharma 2017";
char* status = "Welcome Anish Sharma";
uint8_t i = 0;
for(i=0;i<80;i++)
putChar(' ',i,24,STATUS_COLOR);
write_string_line(STATUS_COLOR,status,24);
clrscr();
print("The KERNEL has been loaded successfully at 0x1000 (memory address)");
print(str);
print(">>>");
update_cursor(3,2);
for(i=0;i<80;i++)
{
putChar(0xdb,i,3,i);
}
for(i=0;i<80;i++)
{
putChar(0xdb,i,4,i);
}
for(i=0;i<80;i++)
{
putChar(0xdb,i,5,i);
}
for(i=0;i<80;i++)
{
putChar(0xdb,i,6,i);
}
for(i=0;i<80;i++)
{
putChar(0xdb,i,3,i);
}
}
The output is -
Adding just another -
for(i=0;i<80;i++)
{
putChar(0xdb,i,3,i);
}
The output is -
Can anyone tell me what is causing this problem?

How can I use functions from different projects in Eclipse?

I have 2 C projects in eclipse, each one do a specific work.(In one project I have dataCatcherXML.c and in the other project I have main.c)
The 1st take the value of some variables from a specific xml code and the other one has variables that must have the value taken in XMLdataCatcher.
Each one works in their specific project but If I merge both of the files(dataCatcherXML.c and main.c) in one project, it doesn't work.(And I don't know why)
So I decided to work with this files in different projects.
My questions is How can I use together this functions from different projects? Is it possible?
dataCatcherXML.C (As you can see here I am taking the value of bit error, bit error is a tag in a XML file)
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <xmlmemory.h>
#include <parser.h>
#include <xmlstring.h>
#include "crc.h"
void XMLdataCatcher(int argc, char **argv) {
xmlDocPtr doc;
xmlNodePtr root;
xmlNodePtr node;
xmlNodePtr children;
xmlNodePtr children2;
doc = xmlParseFile("/home/practicante/XML/prueba1.xml");
if (!doc) {
printf("Error al cargar documento XML\n");
}
root = xmlDocGetRootElement(doc);
node = root->xmlChildrenNode;
while (node != NULL ) {
children = node->xmlChildrenNode;
while (children != NULL ) {
**//In this part I am taking the value of bit_error from the XML file**
if (!(xmlStrcmp(node->name, "bit_error"))) {
printf("%s: %s\n", node->name, xmlNodeGetContent(node));
printf("%s\n", bit_error);
strcpy(bit_error, xmlNodeGetContent(node));
printf("%s\n", bit_error);
}
children2 = children->xmlChildrenNode;
while (children2 != NULL ) {
printf("%s: %s\n", children->name, xmlNodeGetContent(children));
children2 = children2->next;
}
children = children->next;
}
node = node->next;
}
printf("bit_error2 = %d", 1);
}
main.c:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <xmlmemory.h>
#include "crc.h"
#include <parser.h>
#include <xmlstring.h>
#define BIT_SINCRONIA 0X47
#define PID_PAT 0X00
#define table_pat 0x00
FILE *fp2;
int main() {
unsigned short bit_error = 0; // **This part should be: unsigned short bit error = (the value taken in dataCatcherXML)**
bit_error = bit_error << 15;
unsigned short init_payload = 1;
init_payload = init_payload << 14;
unsigned short transport_priority = 0;
transport_priority = transport_priority << 13;
unsigned short PID = PID_PAT;
PID = transport_priority ^ PID;
PID = bit_error ^ PID;
PID = PID ^ init_payload;
unsigned short PID1 = PID >> 8;
unsigned short PID2 = PID;
......... the rest of the code is irrelevant
}
Thanks in advance.
It's hard to give a sane answer to such question, but I'll try with some variants.
Simple one: just copy (or link) the file from one project to another. You will need to remember about syncing it between two projects if any changes happens.
Do It In Eclipse Way: well, this one is kindly ironic, but if you really want to do it as Eclipse wants you to do it you can try this. Create a separate project. This project would contain only this dataCatcherXML.c. This project should compile into a static (because it's easier than shared) library, let's say: datacarcherxml.a. In other projects requiring this library you need to set dependencies on the datacatcherxml.a and add a library from other project. If you do that correctly datacatcherxml will be rebuild if required. Well, it's a little baroquesque, but what would you expect from IDE designed originally for Java? (Ok, it was a litle trolling, sorry about that).
To be honest, it would work that way for Java projects, I'm not sure about the CDT plugin. I'm using Eclipse only for Java. I'm rather old-schooler and I prefer well-configured vim for C/C++ development.

Resources