Reading kernel information in Linux with C/C++ - c++

It happens sometimes that I need to retrieve some system data like CPU usage, process information etc.. which I commonly find in /proc/.... What I do from C/C++ is to read the correct file in /proc/..., parse it and get the information. This is quite bothering and somehow to be kernel version dependent. Is this the correct way to go?

Unfortunately, the Linux kernel doesn't offer any system calls which can be used to retrieve the kind of system information that's exposed via /proc. Your best bet in that case is to keep using that file system.
If it makes you feel any better, all the tools like top, ps or htop all use the /proc filesystem. You should check out their sources if you're having trouble with using it.

Related

Shutting down fan c++ [duplicate]

Is there a Windows standard way to do things such as "start fan", "decrease speed" or the like, from C/C++?
I have a suspicion it might be ACPI, but I am a frail mortal and cannot read that kind of documentation.
Edit: e.g. Windows 7 lets you select in your power plan options such as "passive cooling" (only when things get hot?) vs. "active cooling" (keep the CPU proactively cool?). It seems the OS does have a way to control the fan generically.
I am at the moment working on a project that, among other things, controls the computer fans. Basically, the fans are controlled by the superIO chip of your computer. We access the chip directly using port-mapped IO, and from there we can get to the logical fan device. Using port-mapped IO requires the code to run in kernel mode, but windows does not supply any drivers for generic port IO (with good reason, since it is a very powerful tool), so we wrote our own driver, and used that.
If you want to go down this route, you basically need knowledge in two areas: driver development and how to access and interpret superIO chip information. When we started the project, we didn't know anything in either of these areas, so it has been learning by browsing, reading and finally doing. To gain the knowledge, we have been especially helped by looking at these links:
The WDK, which is the Windows Driver Kit. You need this to compile any driver you write for windows, With it comes a whole lot of source code for example drivers, including a driver for general port-mapped IO, called portio.
WinIO has source code for a driver in C, a dll in C that programmatically installs and loads that driver, and some C# code for a GUI, that loads the dll and reads/writes to the ports. The driver is very similar to the one in portio.
lm-sensors is a linux project, that, among other things, detects your superIO chip. /prog/detect/sensors-detect is the perl program, that does the detecting, and we have spent some time going through the code to see how to interface with a superIO chip.
When we were going through the lm-sensors code, it was very nice to have tools like RapidDriver and RW-everything, since they allowed us to simulate a run of sensors-detect. The latter is the more powerful, and is very helpful in visualising the IO space, while the former provides easier access to some operations which map better to the ones in sensors-detect (read/write byte to port)
Finally, you need to find the datasheet of your superIO chip. From the examples, that I have seen, the environment controllers of each chip provide similar functionality (r/w fan speed, read temperature, read chip voltage), but vary in what registers you have to write to in order to get to this functionality. This place has had all the datasheets, we have needed so far.
If you want something real quick to just lower fans to a level where you know things won't overheat, there's the speedfan program to do so. Figuring out how to configure it in the early versions to automatically lower fans to 50% on computer startup was so painful that my first approach was to simply byte-patch it to start the only superio managed fan I had at lower speed. The newer versions are still bit tough but it's doable - there's a graphical slider system that looks like audio equalizer except that the x axis is temp and y is fan speed. You drag them down one by one. After you figure out how to get manual control for the fan you want, this is next step.
There's a project to monitor hardware (like fans) with C#:
http://code.google.com/p/open-hardware-monitor/
I haven't extensively looked at it, but the source code and use of WinRing0.sys atleast gives the impression that if you know what fan controller you have and have the datasheet, it should be modifiable to also set values instead of just getting them. I don't know what tool is suited (beside kernel debugger) to look at what Speedfan does, if you preferred to snoop around and imitate speedfan instead of looking at the datasheets and trying things out.
Yes, It would be ACPI, and to my knowledge windows doesn't give much/any control over that from user space. So you'd have to start mucking with drivers, which is nigh impossible on windows.
That said, google reveals there are a few open source windows libraries for this for specific hardware... so depending on your hardware you might be able to find something.
ACPI may or may not allow you to adjust the fan settings. Some BIOS implementations may not allow that control though -- they may force control depending on the BIOS/CMOS settings. One might be hard-pressed for a good use case where the BIOS control (even customized) is insufficient. I have come across situations where the BIOS control indeed was insufficient, but not for all possible motherboard platforms.
WIndows Management Instrumentation library (WMI) does provide a Win32_Fan Class and even a SetSpeed method. Alas, the docs say this is not implemented, so I guess it's not very helpful. But you may be able to control things by setting the power state.

Is there any ways to use msinfo32.exe in my program?

I'm writing a program to maintain computers at my workplace. I want to use msinfo32 to automatically collect system information about computers in network remotely and use this data in my program.
The only way I found is to manually connect using interface of msinfo32, export all data and then parse it with my program. But I want to improve this process and do it automatically, update all info automatically etc.
Is there any way I could collect all pc info remotely using msinfo32 from inside of my program?
Please, send me link to how-to with code examples, or explain why I can not do this or how I could.
Sorry for my english, thank you for your attention.
UPD: possibly, I can run msinfo32.exe from inside, but I rather use library than running external program in cmd.
Depends on what exactly do you need to gather. You have some WinApi functions and classes that can give you the system info.
GetSystemInfo() or Computer System Hardware Classes
But I think it's not that bad to use msinfo32.exe directly if it works.
You can't. You should use WINAPI functions, because msinfo32 does not provide console output interface, which could be best solution.
Related: How do I get hardware info such as CPU name, total RAM, etc. with VB6?
You can also use registry keys to check any system settings, all documentation is in the net. Getting system information using registry is not reliable, though.
Msinfo32 documentation
I don't know if in 2015 there was already the "/nfo" option that allows you to have all the results exported to a file.
So just execute:
msinfo32 /nfo "c:\delme\msinfo32.nfo"
and then, via XML, read the desired results.

linux -- getting from /proc/partitions contents to something I can 'ls'

I am writing (yet another) file manager (to learn stuff:) and have a silly/stupid block.
On Linux, to enumerate the storage devices which can contain files, I believe the best approach is to parse the contents of the /proc/partitions file and extract the /dev/sda* entries. (right?) However, how can I map the /dev/sda* to something that I can explore programmatically to get directory contents? I am planning on using boost/filesystem, but since I cannot ls /dev/sda I assume I cannot use boost to iterate over it.
Synopsis: how can I convert /dev/sda* to something that I can 'ls'
I think you're mis-understanding exactly what /dev/sd* actually are to a program. They are devices not directories. You use the mount command to tell the operating system to "interpret" the device as a filesystem, and to attach it somewhere (root, or otherwise). It's this step that makes it into "a directory" somewhere on your filesystem. So other than raw I/O commands (which you don't want to do), get the filesystem mounted, and THEN try and explore it.
It's kind of like opening a file really. When you do this, the operating system gives your program a stream of bytes that you can randomly access the file through. But on the disk, that file could actually be scattered all over the hard drive (or whatever device). But the OS is "making" it into a "nice" format for you to deal with transparently. The same is true of the disk itself when accessing directory/file listings.
I hope my example made it clearer as to why what you're trying to do isn't as simple as you think it is.
Off the cuff, I'd say that the output of mount with no arguments might be a faster choice. That should show you the mounted filesystems and devices while /proc would show you all the devices and partitions.
the device /dev/sda* is a block device and needs to be mounted. To be able to ls it you need to have something that can interpret the file system type. First step: identify the file system type, in raw code there is usually a header code in the partition table in the first segment of the harddrive which would just be /dev/sda On a Linux system it would be something like ext3
Next you need to either write or use a library for interfacing with that filesystem, if you get the Kernel source code for Linux it has a LOT of API code for interfacing with common filesystems, and wrappers for standard POSIX calls which is exactly what you're looking for. Things like ls and cwd use system calls to retrieve information about a mounted filesystem, the disk is a block (or sometimes a character) device and you need the ability to talk to it and speak the same language.

what type of windows device driver can modify FindFirstFile and FindNextFile?

i need to add some files to results returned by FindFirstFile and FindNextFile under windows. Is this possible by file system filter driver or what type of drivers?
Thank you
You can do this by File System Filter Driver. But you can do this by implementing a system wide API hook. I have not tried it before but you really don't need to take the pains of writing the drivers and making the system unstable in case of spoiling the driver stack.
System Wide API Hooking
API Hooking Revealed
As pointed out you can use a file system filter driver (legacy or mini-filter, based on fltmgr). However, I would strongly recommend against the system-wide API hooking. Simple reason: if you do it in usermode it's not really going to be system-wide and if you use an SSDT-hook or some hotpatching method you risk the system's stability. An alternative, albeit equally shady as system-wide hooking, would be entry-point stealing. In this case you use the device object of the volume (in which you're interested, just listen for the attach notifications or enumerate them at startup) to find the driver responsible for it and modify the major function entry points in the driver object (Ilho pointed you into the right direction already).
A file system filter driver is the supported method to do just that.
In the latest Windows 7 WDK the sample under 7600.16385.1\src\filesys\miniFilter\minispy provides a good starting point. Biggest problem with mini filters for a private person is to get assigned an altitude for the driver to load at. Because using just any altitude can well lead to BSODs - and in case of FSFDs you might even risk your data integrity (although the kernel steps in with the BSOD to prevent that). You only need to fake IRP_MN_QUERY_DIRECTORY - this is the minor control code you're looking for when you are handling the IRP_MJ_DIRECTORY_CONTROL major control code. All others you can pass through as long as you don't need to allow the file to be opened, read or written and such. How to do that can be seen in the 7600.16385.1\src\filesys\miniFilter\passThrough sample source.

Detecting metadata-only read requests in windows filesystem

I'm developing a kind of filesystem driver. All of read requests that windows makes to my filesystem goes by the driver implementation.
I would like to distinguish between "normal" read requests and those who want to get only the metadata from the file. ( Windows reads first 4K of the file and then stop reading ).
Does Windows mark this metadata reads in some way? It would be very useful in order to treat that two kind of operations in a different way.
In a typical CreateFile call, we have AccessMode, ShareMode, CreationDisposition and FlagsAndAttributes parameters ( being DWORD ), i'm not sure if it's possible to extract some clue of the operation requested.
Thanks for reading :)
I'd advise you to get the SysInternals file monitoring tool. It captures stacktraces for each call, and since it understands PDBs can even show you function names. That should allow you to figure out many details of this particular call.
On rereading, it appears that the question is looking at the wrong place for an optimization. Why not treat every request for the first 4KB as a request for metadata? There is very little harm in that assumption.
An assumption the other way around would be harmful, if you're doing 100 MB of real I/O when you really only needed 4KB. But if you need 100 MB, a small optimization for the first 4KB causes at most a one-time small hickup for an inherently lengthy operation.
It's not Windows, but Windows Explorer that performs scanning of files to extract metadata. Moreover, you will also face the reads to create thumbnails.
Reporting the drive as a remote / network to Windows will make Explorer read less information and reduce load on the file system, but unfortunately there seems to be no way to block such reading completely.