Introduction to Windows API with C++

Introduction to Windows API with C++

Operating Systems play a critical role in day to day user productivity and experience. Since it's debut, Microsoft has been consistently providing cutting edge research and features to its flagship windows operating systems. Also, according to a report by marketshare, windows has more than 87% of operating systems market share. So, it is only logical for developers to keep windows users in mind too while developing the application.

One of the most helpful resources for developing any application or tool for windows operating systems is the documentation by Microsoft Developers Network, MSDN. It contains detailed and in depth documentation about useful windows API classes and methods

C++ Development with windows API.

To get the basic understanding of the windows application development environment, we will fire up the visual studio. Visual Studio is an Integrated Development Environment by Microsoft to Develop for various types of applications including but not limited to mobile, web, Desktop, Gaming etc. It can be downloaded from visualstudio.microsoft.com

Fire up the Visual Studio once installed and you should be greeted with the following screen.

image.png Click on "Create a new project".

image.png Select Console app and click next.

Once you are done specifying the location and click on create, you should be presented with the following screen

image.png The middle portion is where you will write your code.

C++ code to get Valid Drives

First we will need to import necessary libraries with definitions and classes needed for our program

image.png We have included iostream, windows.h and fileapi.h libraries with import directives. Iostream for input output related operations, windows.h for windows specific classes and definitions and fileapi.h for the functions that we would need to get the filesystem access

Once done, we can move forward to writing the main function of the program

image.png This might seem overwhelming at first, so we will analyze this snippet of code, line by line.

To get the valid drives on the system programmatically, we can use GetLogicalDriveStringsW function of fileapi.h library. We can get more details on the implementation of GetLogicalDriveStringsW on msdn

image.png With the GetLogicalDriveStringsW function, we can get the buffer filled with the string of valid drives in the system. It takes two parameters, one being the buffer of type LPWSTR which will be filled by the function with string and other would be the DWORD length of the buffer

First, we have defined a variable named nBufferLength of type DWORD and initialized it with the value of 20. Here DWORD means 32-bit unsigned integer.

Same way, we have defined a variable named lpBuffer of type LPWSTR. LPWSTR is a 32-bit pointer to a string of 16 bit unicode characters. We have also allocated memory of size 20 to the lpBuffer. As lpBuffer is of type LPWSTR, we are typecasting the malloc call with (LPWSTR).

We have called the function with GetLogicalDriveStringsw(nBufferLength, lpBuffer). As buffer is of type LPWSTR, we cannot print the content of the buffer with std::cout, we have printed the content of the buffer with std::wcout.

We can now build and run the solution. Either go to build menu and click build solution or press F5

image.png Apart from getting the Logical Drives as a string, we can also get a BitMask value of the valid drives on the system with _getdrives() function.

image.png To get more details on the function, we can refer to the corresponding msdn page

image.png The _getdrives() function returns a bitmask which is composed of all the currently available disk drives. In the BitMask, Bit position 0 would be drive A, bit position 1 would be drive B and so on. If function fails, 0 is returned. So, to enumerate all valid drives, we can use a loop to check all bit positions. Firstly we will check the last bit of the bitmask, if it is 1, then we have a valid drive A:\, otherwise we do not have a drive A:. In either case, we shift the bitmask to right by one, so we would get the value at position 1 and so on.

This is continued until value of the BitMask is 0

Another interesting addition to this project would be to figure out the space available on the drive we discovered. For the purpose of getting free space of a drive, we can implement, GetDiskFreeSpaceEx() function, looking at the definition,

image.png The GetDiskFreeSpaceEx() function takes a total of 4 arguments. The drive letter of the drive we want the free space returned, and 3 PULARGE_INTEGER variables to store the data returned from the function

To add the feature of getting free disk space, we make certain changes to our original snippet of code. It should look as follows.

image.png As the GetDiskFreeSpaceEx method needs the drive letter of the format LPWSTR, we use the typecast to convert the drive variable to LPWSTR.

Now, our Get Disk Free Space Ex method will be returning various values when called such as free bytes available to the caller application, total number of bytes and total number of free bytes. As all these numbers will be large, we need to convert them to PULARGE_INTEGER type with typecasting. When run, it will give following output

image.png It can also be converted to Megabytes as well as Gigabytes,

Divide the bytes by (1024*1024) to get Megabytes and divide (1024*1024*1024) to get Gigabytes.

image.png

image.png Conclusion

With C++ windows developers getting paid as much as $100k, It is never better time than now to learn c++ development in windows api.