C # Calling Windows APIs (Part 1)

Source: Internet
Author: User
I have previously written a series of articles that Use WMI to obtain system information. It is true that WMI can hate to easily implement many features we want to implement, however, in some cases, it is difficult for us to use WMI to implement some complex functions. For example, in a recent project, one of the functions is to change the current system time, WMI is difficult to implement (I have not found any relevant method), and there are some other features that are difficult to implement Through WMI, maybe it is the reason why WMI requires high permissions for execution. Therefore, although we do not want to, we have to call the Windows API. This document describes how to call windows system APIs in C.
This article explains the following steps:
API Overview
Correspondence between simple data types in C # and API data types
How to pass complex parameters when calling an API: encapsulation class, structure, and Union
How to call an API
How to ensure successful API calls

API Overview
Windows API (Application Programming Interface) is a series of function interfaces opened by Microsoft to facilitate the majority of Windows developers to call the underlying functions of the system .. Many of the functions in. NET are encapsulation of the underlying API of the system, but. Net does not contain all the API functions in windows. Fortunately, in. net, we are allowed to call the system's API functions, and can also pass input or output parameters to the system API as needed.

When an unmanaged API function is called, it performs the following operations in sequence:
1. Find the DLL that contains the function.
2. Load the DLL to the memory.
3. find the address of the function in the memory and push its parameters to the stack to block the required data (Note: only when the function is called for the first time, to find and load the DLL and find the address of the function in the memory .).
4. transfer control to an unmanaged function.
5. Platform call for unmanaged DLL Functions
A platform call causes an exception generated by an unmanaged function to the hosted caller.

The DLL Function Identifier includes the following elements:
Function name or serial number
Name of the DLL file to which the Implementation resides

For example, if you specify the MessageBox function in user32.dll, You need to identify the function (MessageBox) and its location (user32.dll, USER32, or USER32 ). The Microsoft Windows Application Programming Interface (Win32 API) can contain two versions of each character and string processing function: the single-byte character ANSI version and the double-byte character Unicode version. If this parameter is not specified, the charset field indicates that the character set is ANSI by default. Some functions can have more than two versions.

Messageboxa is the ANSI entry point of the MessageBox function, while messageboxw is a unicode version. You can run various command line tools to list function names for specific DLL (such as user32.dll. For example, you can use dumpbin/exports user32.dll or link/dump/exports user32.dll to obtain the function name.

You can rename an unmanaged function to any desired name in code, but map the new name to the initial entry point in the DLL. For instructions on Renaming an unmanaged DLL function in the hosted source code, see the specified entry point.

Platform calls allow you to call Win32 APIs and other DLL functions to control a large part of the operating system. In addition to Win32 APIs, there are many other APIs and DLL that can be called through the platform.

The following describes some commonly used DLL in Win32 APIs.
Gdi32.dll: A graphical device interface (GDI) function for device output, for example, a function for drawing and font management.
Kernel32.dll: a low-level operating system function for memory management and resource processing.
User32.dll: A Windows Management function used for message processing, timers, menus, and communication.

When it comes to function calls, you naturally have to provide parameters to the system API or obtain the returned values after calling the system API. Because Windows uses C/C ++ for development, the program language we call is C #, and the Data Types of the two will naturally be inconsistent. The following table lists a correspondence between the two.

The following table lists the data types used in Win32 APIs (listed in wtypes. h) and C style functions. Many non-writable libraries contain functions that pass these data types as parameters and return values. The third column lists the corresponding. NET Framework built-in value types or classes used in managed code. In some cases, you can replace the types listed in this table with the same size.

Unmanaged type in wtypes. h Unmanaged C language type Managed class name Description

Handle

Void *

System. intptr

32-bit windows and 64-bit windows.

Byte

Unsigned char

System. byte

8-digit

Short

Short

System. int16

16-bit

Word

Unsigned short

System. uint16

16-bit

Int

Int

System. int32

32-bit

Uint

Unsigned int

System. uint32

32-bit

Long

Long

System. int32

32-bit

Bool

Long

System. int32

32-bit

DWORD

Unsigned long

System. uint32

32-bit

Ulong

Unsigned long

System. uint32

32-bit

Char

Char

System. Char

It is modified with ANSI.

Lpstr

Char *

System. string or system. Text. stringbuilder

It is modified with ANSI.

Lpcstr

Const char *

System. string or system. Text. stringbuilder

It is modified with ANSI.

Lpwstr

Wchar_t *

System. string or system. Text. stringbuilder

Use Unicode.

Lpcwstr

Const wchar_t *

System. string or system. Text. stringbuilder

Use Unicode.

Float

Float

System. Single

32-bit

Double

Double

System. Double

64-bit

How to pass complex parameters when calling an API: encapsulation class, structure, and Union
The class and structure are similar in. NET Framework. They can all have fields, attributes, and events. They also have static and non-static methods. A major difference is that the structure belongs to the value type and the class belongs to the reference type.
Structure:
For example, if a common function is used to obtain the date and time, the original declaration is as follows:

VOID GetSystemTime(LPSYSTEMTIME lpSystemTime);

This method is located in the kernel32.dll class library. This method requires a systemtime structure. Its original declaration is as follows:
Typedef struct _ systemtime {
Word wyear;
Word wmonth;
Word wdayofweek;
Word wday;
Word whour;
Word wminute;
Word wsecond;
Word wmilliseconds;
} Systemtime, * psystemtime;

Based on the correspondence between simple data types in C # And Data Types in C/C ++, we can complete the following code:

Public struct systemtime
{
Public ushort wyear;
Public ushort wmonth;
Public ushort wdayofweek;
Public ushort wday;
Public ushort whour;
Public ushort wminute;
Public ushort wsecond;
Public ushort wmilliseconds;

}

The preceding API method call declaration is as follows:
[Dllimport ("kernel32.dll", entrypoint = "setsystemtime")]
Public static extern void getsystemtime (
Systemtime
);

By default, the above method passes the in/out parameter of the systemtime class. This parameter must be declared using the inattribute and outattribute attributes, because classes of the reference type are passed as input parameters by default. To enable the caller to receive results, these direction attributes, such as ref or out, must be explicitly applied.
In addition, we also need to specify the layout of the structure in the memory, which can be specified by the structlayout attribute when the structure is declared. The structlayout attribute requires an enumerated value of layoutkind. It has the following values:

Member name Description
Auto The runtime automatically selects an appropriate layout for the members of objects in the unmanaged memory. Objects defined using this enumeration member cannot be exposed outside the hosted code. An exception occurs when you try this operation.
Explicit The precise position of each member of an object in the unmanaged memory is explicitly controlled. Each member must use fieldoffsetattribute to indicate the position of the field in the type.
Sequential The object members are arranged in sequence when they are exported to the unmanaged memory. These members are laid out based on the encapsulation specified in structlayoutattribute. Pack and may be discontinuous.

In this example, use sequential. The above C # structure description is revised as follows:
[Structlayout (layoutkind. Sequential)]
Public struct systemtime
{
Public ushort wyear;
Public ushort wmonth;
Public ushort wdayofweek;
Public ushort wday;
Public ushort whour;
Public ushort wminute;
Public ushort wsecond;
Public ushort wmilliseconds;

}

Of course, you can declare it as explicit, as shown below:

[Structlayout (layoutkind. explicit, size = 16, charset = charset. ANSI)]
Public struct mysystemtime
{[Fieldoffset (0)]
Public ushort wyear;
[Fieldoffset (2)]
Public ushort wmonth;
[Fieldoffset (4)]
Public ushort wdayofweek;
[Fieldoffset (6)]
Public ushort wday;
[Fieldoffset (8)]
Public ushort whour;
[Fieldoffset (10)]
Public ushort wminute;
[Fieldoffset (12)]
Public ushort wsecond;
[Fieldoffset (14)] public ushort wmilliseconds;
}
Fieldoffset of each field increases by 2 bytes in sequence, because the memory size occupied by strict ushort is exactly 2 bytes. A total of 8 fields, so a total of 16 bytes. Here, a charset attribute declaration is used to specify the character set to be used for sending a string. It is also an enumeration type. The possible values and corresponding descriptions are as follows:

Member name Description
Auto The target operating system automatically mails strings as appropriate. Unicode is the default value for Windows NT, Windows 2000, Windows XP, and Windows Server 2003; ANSI is the default value for Windows 98 and Windows ME. Although the default value of the Common Language Runtime Library is auto, You can override this default value in the language. For example, by default, C # marks all methods and types as ANSI.
ANSI Returns a string in the form of a multi-byte string.
None This value is out of date and has the same behavior as charset. ANSI.
Unicode Returns a string in the form of Unicode 2-byte characters.

To be continued .....

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.