Safe subclassing in Win32 (Security subclass in Win32)

Source: Internet
Author: User

Safe subclassing in Win32 (Security subclass in Win32)
Kyle marsh
Microsoft Developer Network Technology Group
Created: January 25,199 4
Translator: bbe & bfe

General idea
This article describes the subclassing Technology in the Win32 environment, how it is implemented, and the rules that must be followed to ensure subclass Security (rules ). The entire article covers the subclass of instances and global. Superclassing is described as an optional (alternative) part of the global subclass.

No significant (dramatically) changes have taken place in subclass from Win16 to Win32. However, in Win32, some new subclass rule applications must follow. The most important (and most obvious) is that an application cannot subclass a window or class belonging to other processes. This rule cannot be broken, but some workarounds (this word is not translated) applications can use it.

1. Definition of subclassing
Subclass is a technology that allows an application to intercept messages sent to other windows. An application can add, monitor, or modify the default behavior of a window by intercepting messages used by other windows ). Subclass is a fast and efficient way to change or expand the behavior of a window, and you do not need to re-develop this window. Subclass default control window class (button control, Edit Control, list control, Combo control, static control and scroll bar Control) is a convenient way to obtain the control function and modify its behavior. For example, if a multiline editing control is included in a dialog box and you press enter, the dialog box is closed. When you press enter, a program can insert a carriage return symbol and wrap the text without exiting the dialog box. To meet the needs of an application, you do not need to re-develop an editing control through subclass technology.

2. Basics
The first step to create a window is to fill in the wndclass structure and call registerclass function registration (Register) a window class. Wndclass structure; an element is the address of window procedure. When a window is created, the 32-bit Microsoft Windows Operating System reads the window process address in the wndclass structure and copies it to the information structure of the new window ). When a message is sent to the window, Windows calls the corresponding Window Process by the address saved in the window information structure. To subclass a window, you can replace the original window process address with the new window process address so that a new window process receives all messages sent to the original window.
When an application subclass a window, it can perform three actions on the message: (1) passing the message to the original window; (2) modify the message and pass it to the original window. (3) do not send the message any more.
An application that subclass A window can decide when to respond to the messages it receives. This program can process the message before or after the process of sending the message to the original window, or before and after the message (the application can process the message before, after or both before and after passing the message to the original window procedure .)

3. Types of subclassing subclass type
Subclass has two types: instance subclassing and global subclassing)
The example class refers to subclass the information structure of an independent window. By using the instance subclass, only messages of a specific window instance will be sent to the new window process (it only substitutes the address of window procedure in the window's information structure, not wndclass structure. we can see from the topic "The Basics", each window has its own information structure .)
Global subclass refers to replacing the window process address in the wndclass structure of a window class. All the windows of the window class created later have the replaced window process address. Global subclass only affects the window created after subclass. If any window of the window class already exists during subclass, the existing window is not affected by global subclass. If the program needs to affect the behavior of an existing window, this program must subclass each existing window class instance.

4. Win32 subclass rules
In Win32, there are two subclass rules that are applicable to (apply to) instances and global subclasses.
Subclass can only happen in one process. A program cannot subclass a window or class belonging to another process.
The reason for this rule is simple: Win32 processes have independent address spaces. A window process has its own address. In a different process, the window process has different addresses. As a result, replacing the address of one process from another cannot bring the expected results, so 32-bit Windows does not allow this replacement (that is, (that is ), from a different process ). Setwindowlong and setclasslong functions do not allow subclass of this type. You cannot subclass windows or classes in other processes.
However, there are still some ways to enable you to subclass any process. Once you get a function in the address space of a process, you can subclass any part of the process. There are a few ways to achieve this purpose. The simplest (and most rude) method (approach) is to add a DLL (Dynamic-Link Library) name to the primary key below the registry. HKEY_LOCAL_MACHINE/software/Microsoft/Windows NT/CurrentVersion/Windows/appinit_dlls
This primary key causes windows to add your DLL to all processes in the system. Your dll may need some method to wake up after any subclass event occurs. The wh_cbt Hook can usually do this. Dll can monitor the hcbt_createwnd event and then subclass the expected window. The ctl3d example program uses the wh_cbt hook for subclass, but it does not contain the registry entry that subclass any process. Applications that want to implement ctl3d can link it to their own processes.
Another way to add your subclassing code to any process is to use a system-wide hook. When a hook within the system is called from the context of another process, the system loads the DLL containing the hook into the process. The ctl3d code processes the wh_cbt hook in the same way as the local wh_cbt hook (in fact we called them global hook and thread-specific hook) in the same way ).
The third method is very complicated: it includes using the OpenProcess, writeprocessmemory, and createremotethread functions to inject code to other processes. I don't recommend this method or discuss how to implement it in detail. Jeffrey Richter, a developer who insists on using this method, is one of the top windows programming masters, technical writers, and author of Windows core programming) tell me that he is planning to describe this technology in his recent Win32 Q & A (questions and answers) column in Microsoft Systems journal.
Today, many Windows 3.1 programs subclass other processes to enhance the process and add some cool features. Windows is developing towards an object-oriented system. Object Linking and Embedding (OLE) provides a better way to achieve this function. In future versions of Windows, subclass of other processes may become more difficult, and Ole may become easier. If possible, I recommend that you convert your program to Ole instead of subclass other processes. Subclass processes may not directly use the original window process.
In the Win16 era, a program can directly call the original window process through the return values of setwindowlong or setclasslong. After all, the returned values of these two functions are a function pointer, so why not call them directly? In the Win32 era, this is absolutely impossible (definitive no-no). The value returned from setwindowlong and getclasslong may not be a pointer to the address of the previous window process at all. This occurs in window nt. When an application uses a non-Unicode Window Process to subclass A Unicode window, or a non-Unicode window with a unicode Window Process. In this case, the operating system must perform a conversion between Unicode and ANSI for the messages received in the window. If a program uses a pointer pointing to the structure to call the window process, the program immediately generates an exception. The only way to call the window process by using the value returned from setwindowlong or setclasslong is to pass the returned value as a parameter to callwindowproc.

5. subclassing a window)
Setwindowlong is used to subclass A Window instance. The program must have the address of the subclass function. A subclass function is a function that receives messages from a window and transmits them to the original window. Subclass functions must be exported to the module definition file of a program or DLL (The subclass function must be exported in the application's or the DLL's module definition file .).
Programs that want to subclass A Window use the handle of the window, gwl_wndproc option (defined in windows. h), and the new subclass function address to call the setwindowlong function. Setwindowlong returns a DWORD value, which is the address of the original Window Process of the window. The program must save the address to pass the intercepted message to the original window and remove the subclass from the window. Call callwindowproc by using the address of the original Window Process and the hwnd, message, wparam, and lparam parameters in the window message. The program can send the message to the original window process. Generally, the program simply transmits the parameters it receives from windows to callwindowproc.
The program also needs the original window process address to remove the subclass from the window. The program calls setwindowlong again to remove the subclass from the window. The program transmits the original window process address, the gwl_wndproc option, and the quilt-type window handle to the setwindowlong function.
The following code samples subclass an edit control and then remove the subclass.

Long Far Pascal subclassfunc (hwnd, uint message, wparam, long lparam );
Farproc lpfnoldwndproc;
Hwnd heditwnd;
//
// Create an edit control and subclass it.
// The details of this particle edit control are not important.
//
Heditwnd = createwindow ("edit", "edit test ",
Ws_child | ws_visible | ws_border,
0, 0, 50, 50,
Hwndmain,
Null,
Hinst,
Null );
//
// Now subclass the window that was just created.
//
Lpfnoldwndproc = (farproc) setwindowlong (heditwnd,
Gwl_wndproc,
(DWORD) subclassfunc );
.
.
.
//
// Remove the subclass for the Edit Control.
//
Setwindowlong (heditwnd, gwl_wndproc, (DWORD) lpfnoldwndproc );
 
//
// Here is a sample subclass function.
//
Long Far Pascal subclassfunc (hwnd,
Uint message,
Wparam,
Long lparam)
{
//
// When the focus is in an edit control inside a dialog box,
// Default enter key action will not occur.
//
//
If (Message = wm_getdlgcode)
Return dlgc_wantallkeys; // The application will process all keyboard inputs itself.
Return callwindowproc (lpfnoldwndproc, hwnd, message, wparam, lparam );
}
Potential defects of potential pitfalls
The instance subclass is normal, but note that the following rules can ensure security.

When subclass a window, you must know who is responsible for the window's behavior. For example, Windows is responsible for all the controls it provides, and the program is responsible for all the windows it defines. Sub-classes can be used for any window in the same process. However, when a program subclass a window that is not in charge of it, this program must ensure that the subclass function does not destroy the original behavior of the window (original behavior ). Because this program does not control the window, it cannot rely on any information about the window, because the components responsible for the window may change in the future. A subclass function should not use extra window bytes (extra window bytes) and Class bytes (class bytes) in the window ), unless it knows exactly what these bytes mean and how to use them during the original window process. Even if this program is familiar with additional window bytes and class bytes, it should not use them unless the program decides to update the window and change some aspects of these extra bytes, otherwise, the subclass process may fail. For this reason, Microsoft recommends that you do not subclass the control class. Windows is responsible for the controls it provides, and some aspects of the control may change with the change of the Windows version. If your program must subclass A control provided by Windows, you may have to update your code when the new Windows version is released (release.
Because instance subclassing occurs after the window is created, the program of the subclass window cannot add any extra bytes (extra bytes) to the window ). The program should put the data to be stored in the property list of the quilt-type window ).
You can set the properties of a window. The program calls the setprop function using the window handle, a string that identifies the attribute, and a handle pointing to the data. The handle pointing to the data is usually obtained by calling localalloc or globalalloc. When a program needs to use the data in the window property list, it can call the getprop function with the handle of the window and the string that identifies the property as a parameter. Getprop returns the data-directed handle set by setprop. When the program uses the data, or the window is about to be destroyed, the program must call removeprop to remove these properties from the window property list, the parameter is the string identifier of the window handle and attribute. Removeprop returns the data handle. In this case, the program uses these handles to call localfree or globalfree to release the memory.
If a program subclass a window that has already been subclass-type, it must be removed in reverse order when the subclass is removed.

6. Global subclass (subclassing a window class)
Global subclass is similar to instance subclass. The program calls setclasslong to subclass A window class globally ). Like subclass, a program needs the address of the subclass function, and the subclass function must be exported in the module definition file of the program or DLL.
To globally subclass A window class, the program must have a window handle for the window class. To obtain the window handle of the expected window class, most programs create a window of the corresponding class. To remove a subclass, a program needs a window handle pointing to its subclass window class. Therefore, creating and maintaining a window for this purpose is the best technique (technique ). If a program creates a window of classes that it wants to subclass, the window is usually hidden. After obtaining the correct window handle for the window class, the program uses the window handle, gcl_wndproc option (defined in windows. h), and the address of the subclass function to call setclasslong. setclasslong returns a DWORD value, which is the original window process address of the window class. At this time, by calling callwindowproc, the program can send messages to the original window process. The program can call setclasslong again to remove sub-classes. You only need to change the sub-classes function address to the original window process address.

The following code globally subclasses and removes a subclass to an edit control:

Long Far Pascal subclassfunc (hwnd, uint message, word wparam,
Long lparam );
Farproc lpfnoldclasswndproc;
Hwnd heditwnd;
 
//
// Create an edit control and subclass it.
// Notice that the edit control is not visible.
// Other details of this particle edit control are not important.
//
Heditwnd = createwindow ("edit", "edit test ",
Ws_child,
0, 0, 50, 50,
Hwndmain,
Null,
Hinst,
Null );
Lpfnoldclasswndproc = (farproc) setclasslong (heditwnd, gcl_wndproc, (DWORD) subclassfunc );
.
.
.
//
// To remove the subclass:
//
Setclasslong (heditwnd, gwl_wndproc, (DWORD) lpfnoldclasswndproc );
Destroywindow (heditwnd );
Potential Defects
Global subclass is the same as instance subclass. The program should not try (attempt to) to use the extra bytes of the window class or window (extra bytes ). Unless it knows exactly (exactly) How the original process uses them. If you must attach data to a window, you should use the window property list as subclass to the instance.
In Win32, global subclass does not affect the classes of other processes or the Windows previously created from these window classes. This is a very important change from the Win16 environment. Windows maintains separate window class information for each Win32 process in the system. For more information about windows, see the "window classes in Win32" Technical article in The msdn library. Currently, global subclass does not affect other processes, which has become a useful technology for developers. In Win16, global subclass is not encouraged, because it affects all windows of the subclass window class-not only the execution of subclass programs, but the entire system. This is not what the program usually wants, so the program can only use inconvenient and not powerful (less powerful) Methods to change the window behavior of system class creation. It is very easy to use global subclass in Win32.

7. superclassing superclass
Subclassing a window class causes messages meant for the window procedure to be sent to the subclass function. the subclass function then passes the message to the original window procedure. superclassing (also known as class cloning) creates a new window class. the new window class uses the window procedure from an existing class to give the new class the functionality of the existing class. the superclass is based on some other window class, known as the base class. frequently the base class is a Windows-supplied control class, but it can be any window class.
Subclass A window class causes messages sent to the window process to be sent to the subclass function ). The subclass function then passes the message to the original window. Superclassized superclassing (also known as class cloning) creates a new window class. The new window class uses the Window Process of the existing class to make the new window class have the function of the existing class (functionality ). Superclassization makes existing classes based on other window classes called base classes.
Note: Do not superclass the scroll bar control class because Windows uses the class name to produce the correct behavior for scroll bars.
Note: do not subscribe to the scroll bar control class, because Windows uses the name of this class to correctly process the action of the scroll bar.
The superclass has its own window procedure, the superclass procedure, which can take the same actions a subclass procedure can. the superclass procedure can take three actions with the message: (1) pass the message directly to the original window procedure; (2) modify the message before passing it to the original window procedure; (3) not pass the message. the superclass can react to the message before, after, or both before and after passing the message to the original window procedure. the superclass procedure has its own window process ).
It can have the same behavior as subclass procedure. The superclass can perform three actions on messages: (1) directly passing messages to the original window; (2) Modifying messages before passing messages to the original window; (3) no message is transmitted. Superclass can respond to messages before, after, or before, when they are passed to the original window.
Unlike a subclass procedure, a superclass procedure into es create (wm_nccreate, wm_create, and so on) messages from windows. the superclass procedure can process these messages, but it must also pass these messages to the original base-class window procedure so that the base-class window procedure can initialize.
Unlike the subclass process, a superclass process receives the created message (create message just like wm_nccreate, wm_create, and so on ). the super-class process can process these messages, but it must pass these messages to the base-class window process so that the base-class window process can be initialized.
The application callgetclassinfo to base a superclass on a base class. getclassinfo fills a wndclass structure with the values from the base class's wndclass structure. the application that is superclassing the base class then sets the hinstance field of the wndclass structure to the instance handle of the application. the application must also set the wndclass structure's lpszclassname field to the name it wants to give this superclass. if the base class has a menu, the application superclassing the base class must supply a new menu that has the same menu IDS as the base class's menu. if the superclass intends to process the wm_command message and not pass the message to the base class's window procedure, the menu does not have to have corresponding IDs. getclassinfo does not return the lpszmenuname, lpszclassname, or hinstance field of the wndclass structure.
The last field that must be set in the superclass's wndclass structure is the lpfnwndproc field. getclassinfo fills this field with the original class window procedure. the application must save this address so that it can pass messages to the original window procedure with a call to callwindowproc. the application must put the address of its subclass function into the wndclass structure. this address is not a procedure-instance address because registerclass gets the procedure-instance address. the application can modify any other fields in the wndclass structure to suit the application's needs.
The application can add to both the extra class bytes and the extra window bytes because it is registering a new class. the application must follow two rules when doing this: (1) the original extra bytes for both the class and the window must not be touched by the superclass for the same reasons that an instance subclass or a global subclass shocould not touch these extra bytes; (2) if the application adds extra bytes to either the class or the window instance for the application's own use, it must always reference these extra bytes relative to the number of extra bytes used by the original base class. because the number of bytes used by the base class may be different from one version of the base class to the next, the starting offset for the superclass's own extra bytes is also different from one version of the base class to the next.
After the wndclass structure is filled, the application callregisterclass to register the new window class. windows of this class can now be created and used.
Applications often used superclassing in Win16 because global subclassing was discouraged. now that global subclassing is no longer discouraged in Win32, superclassing has lost some of its appeal. you may still find it useful to create a superclass if your application wants to change the behavior for only a subset of the Windows (instead of all windows) created from a system class, which is the effect of global subclassing.
Summing up
Subclassing is a powerful technique that has not changed signiicantly in win32. the only major change is that you can no longer subclass a window or class that belongs to another process. although there are workarounds for this restriction, I recommend that you move your application to Ole rather than relying on subclassing if you need this capability.

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.