The request execution time period is usually referred to as "appy times". Refers to the time period when the system VM stabilizes to the VxDs and ring-3 level application software (especially the 16-bit application). For example, at a specific time period, VxDs can load and invoke functions in 16-bit DLLs. This appy time is not valid in Windows 3.x. In windows3.x, a VxD can contain the address of any function in the 16-bit DLLs and simulate a far call to this address. However, because of the VMM reentrant, this operation interrupts all tasks that are being performed in the ring-3. So the APIs that can be invoked by VxDs are required to be interrupted safely, like PostMessage. In Windows 95, a VxD can invoke any function in 16-bit DLLs with the help of appy time.
If your VxDs is notified to be in appy time, it can load 16-bit DLLs and invoke the function. How does VxDs know Appy time is coming? This will require a appy time with a shell VxD. When the system VM is in a stable state, the Shell VxD invokes a callback function for a VxD that is specified when the VxD requests appy time. Shell vxd occurs once Appy time event only calls your callback function once. It's like looking for a job. You go to the Employment Institute and register your name and telephone number. When you get home, if you have a job for you, the Employment service will call you for the good news. When you get the news, they won't let you know.
It takes some time for the processing to take place before one of the Appy times works. The Appy time event will not work in the following environments:
1, the system starts or shuts down the machine.
2, when the system VM in a critical segment or wait for a semaphore.
Manage a Appy time event
You can register a appy time event by calling _shell_callatappytime, which is defined as follows:
Vxdcall _shell_callatappytime, <<offset32 pfncallback>, Dwrefdata, dwflags, dwtimeout>
Pfncallback-The flat address of the callback function you want the shell VxD to call when the Appy time event occurs. This function receives two parameters, Dwrefdata and dwflags, the same as the two you send to _shell_callatappytime. Remember that the Shell VxD invokes your callback function in the order of C invocation. In short, you have to define your callback function like this:
Beginproc Onappytime, Ccall, public
Argvar Dwrefdata,dword; Declare argument name and type
Argvar dwflags, DWORD
Enterproc
Your code ...
Leaveproc
Return
Endproc Onappytime
Dwrefdata-The reference data you want the shell VxD to send to your callback function. It can be anything you want.
dwflags--Event flags.
One of the following values:
CAAFL_RING0 ring-0 Event
Caafl_timeout the time due event specified by dwTimeOut.
If you only want to wait for the Appy time event within a certain amount of hours, use the CAAFL_TIMEOUT flag. If you want to wait for the Appy time event, use NULL. CAAFL_RING0 effect is unknown.
dwTimeOut-Before the Appy time event occurs, a VxD can wait for the length of a period. The unit of the time period is unknown.
This service is asynchronous, meaning that you return immediately after registering the callback function for the Appy time event.
If the service call is successful, return the Appy time event handle in EAX. If the call fails, return 0 in EAX.
You can call _shell_cancelappytimeevent to undo the Appy time event registration, which has only one argument, which is the Appy time event handle returned by _shell_callatappytime.
You should check the system when the Appy time event arrives. For example, what happens when you register appy time when the system shuts down? Your VxD's callback function will not get called! When the Appy time event arrives, you should call _shell_queryappytimeavailable to query the System state. This service has no parameters. If appy time is invalid, return 0 in eax, for example, when the system shuts down or the message service program produces a general protection error.
This service will not tell you whether it is appy time: it simply tells you that there may be a Appy timer event coming. In short, if you want to run safely, call _shell_queryappytimeavailable first and check that the value in EAX is not a 0 value before you can continue to invoke _shell_callatappytime.
When Appy time arrives, you can use several Shell service calls:
_shell_calldll
_shell_freelibrary
_shell_getprocaddress
_shell_loadlibrary
_shell_localallocex
_shell_localfree
Using the 6 services provided, VxDs can invoke the 16-bit function in the 16-bit Dlls/exe, like WinHelp. However, we are about to advance to the 32-bit era (the future is 64-bit), so I will not study them carefully. If you are interested in this, you can learn about them in the Windows 95/98DDK documentation.
Others only request the execution time period service I want to be more useful: _shell_shellexecute and _shell_broadcastsystemmessage. Using _shell_broadcastsystemmessage, you can send messages to the top window and all VxDs in one call. If appy time is valid, you can send messages to Windows and VxDs. If appy time is invalid, you can only send messages to VxDs.
_shell_shellexecute is the corresponding function in the ring-3 function ShellExecute in the ring-0. In fact, it calls the ShellExecute in ring-3 to do the job. With the shell service, you can run/Open/print any file.
The definition of _shell_shellexecute is as follows:
Vxdcall _shell_shellexecute,<offset32 shexpacket>
It has only one parameter, the shexpacket structure of the tablet address. It returns a value from the ShellExecute function to the EAX. Let's look at the Shexpacket structure:
The number of bytes in the Shex_dwtotalsize shexpacket structure plus the size of the optional parameter rgchbaggage, which follows directly behind this structure. I'll wait and describe rgchbaggage.
The number of bytes in the Shex_dwtotalsize shexpacket structure plus the size of the optional parameter rgchbaggage, which follows directly behind this structure. I'll wait and describe rgchbaggage.
Shex_dwsize shexpacket the number of bytes in the structure, excluding rgchbaggage. Combined with the above shex_dwtotalsize value, the shell VxD calculates the size of the rgchbaggage of any length.
Shex_ibop the action you want to complete. If you specify 0, that means you want to open a file. If it is an executable file, run it. If you want to do something else, you must specify the name of the operation in Rgchbaggage, in which you must include the distance from this shexpacket structure to an ASCII string that specifies the name of the operation you want to complete, with a byte count. The size of the Shexpacket structure is 32 bytes. If the action string is immediately following the Shexpacket structure, the value in Shex_ibop must be 32. To know what you can do, check the ShellExecute service. There are three operations defined, "open", "print" and "explore".
Shex_ibfile the distance from this structure to an ASCII string, which is the file name you want to pass to ShellExecute, like a Shex_ibop member.
Shex_ibparams The optional parameters you want to pass to the file specified by Shex_ibfile. If this file is a document file and you do not want to pass any arguments to it, use 0. If you want to pass the argument to that file, place the distance from this struct to the string specified by this member in this member. In short, just like Shex_ibop and Shex_ibfile members.
Shex_ibdir working directory. If you want to use the Windows directory to specify 0, otherwise specify it as the preferred directory name string after this structure, and place the distance value from the beginning of the structure to the directory name string into this member.
Shex_dwreserved as its name implies, it is reserved. Don't ignore it.
How the Shex_ncmdshow application window is displayed. This is a value you normally pass to ShowWindow, such as the sw_xxxx value. These values can be viewed in windows.inc.
The size of all members is double word. Here I introduce the rgchbaggage members I promised just now. There is only one point difference, because its size is variable, so it cannot be included in the definition of this structure as a member of the shexpacket structure. Looking at Shell.inc, you see that rgchbaggage is not in the definition of shexpacket structure, although in the Windows 9x DDK document, declare that it is a member of the shexpacket structure.
What is Rgchbaggage? In short, it is an array of strings following the shexpacket structure. In this array, you can put the name of the operation you want to complete on the file, the name of the file, the parameters you want to pass to the file, and the working directory. By first getting the distance from the Shexpacket structure to the first character of these strings (that is, some member values of this structure), and then adding these values to the shexpacket structure, the Shell VxD can get the offsets of these strings in the Rgchbaggage array. For example, if the Shexpacket structure starts at 60000h and the string follows, the distance between the structure and the string is the size of the structure itself, 32 bytes (20h). So the shell VxD knows that the string is positioned at 60020h.