Request execution time and shell function
theory:
The request execution time period is usually referred to as "APPY TIME". It means that the time period when the system VM is stable to the interaction of the application software that is allowed VXDS and Ring-3 levels (especially 16-bit applications). For example, in a specific period of time, VxDs can load and call functions in 16-bit DLLs. This APPY Time is invalid in Windows 3.x. In Windows3.x, a VXD can be included in any of the 16-bit dlls, and simulates a far-call to this address. However, since the VMM re-entry, this operation will interrupt all tasks that are executing in Ring-3. So the APIS that can be called by VXDS is required to be safe, like PostMessage. In Windows 95, a VXD can call any function in the 16-bit DLLs with the help of the APPY Time.
If your VXDS is notified in Appy Time, it can load 16-bit dlls and call it. Vxds How do you know what appy time arrives? This should be requested using the shell vxd to request an APPY TIME. When the system VM is in a steady state, the shell vxd will call a callback function of a VXD, which is specified when the VXD request APPY TIME. The APPY TIME event occurs once a APPY TIME event only calls once your callback function. This is like looking for work. You go to your career introduction, register your name and phone number. When you return home, if there is a job that is suitable for you, the career introduction will notify you this good news. When you receive this news, they no longer inform you.
It takes some time for some time before an APPY Time works. APPY TIME events will not work in the following environments:
1. When the system is started or turned off. 2, when the system VM is in the critical section or waiting for a semaphore.
Manage an APPY TIME event
You can register an APPY TIME event by calling _shell_callatappytime, which is defined as follows:
Vxdcall _shell_callatappytime, << Offset32 Pfncallback>, DwrefData, DWFLAGS, DWTIMEOUT>
PFNCallback - The tablet address of the callback function you want to call when the APPY TIME event occurs. This function receives two parameters, dwrefdata, and dwflags, which is transmitted to the _Shell_callatappytime. Remember, shell VXD calls your callback function in C call order. All in all, you have to like this define your callback function: BeginProc OnAppyTime, CCALL, PUBLICArgVar dwRefData, DWORD; declare argument name and type ArgVar dwFlags, DWORD EnterProc your code ... LeaveProc Return EndProc OnAppyTime dwRefData - Shell VxD you want to transfer Give your reference data for your callback function. Can be anything you want. DWFLAGS - Event flag. One of the values: CAAFL_RING0 RING-0 event CAAFL_TIMEOUT is expired by the time specified by DWTIMEOUT. If you just want to wait at a certain time to wait for the APPY TIME event, use the CAAFL_TIMEOUT flag. If you want to wait for the APPY TIME event, use NULL. Caafl_ring0 is unknown. Dwtimeout - VXD can wait for the length of time before the APPY TIME event. The unit of time period is unknown.
This service is asynchronous, meaning that you return to the APPY TIME event to register the callback function. If this service call is successful, return to the Appy Time event handle in EAX. If the call fails, it returns 0 in EAX.
You can call _shell_cancelappytimeeverEvent to undo the appy time event registration, which only has a parameter, 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 your APPY TIME when you are shut down? Your VXD's callback function will not be called! When the appy time event arrives, you should call _Shell_QueryAppyTimeavailable to query the system status. This service has no parameters. If the appy time is invalid, it returns 0 in EAX, for example, when the system is turned off or when the message service program generates a general protective error.
This service will not tell you that is APPY TIME: It only tells you that there may be an APPY TIME event. In short, if you want to run safely, first call _Shell_QueryAppyTimeavailable and check if the value in Eax is a non-zero value, and then continue call _shell_callatappytime.
Request execution time SHELL service
When the appy time arrives, you can use a few shell service calls:
_Shell_calldll _shell_freeelibrary _shell_getprocaddress _shell_loadlibrary _shell_localalocex _shell_localfree
With these 6 services provided, VXDs can call 16-bit functions in 16-bit DLLS / EXE, like WinHelp. However, we must progress to the 32-bit era (the future is 64-bit), so I will not carefully study them. If you are interested in this, you can learn about them in the Windows 95 / 98DDK document.
Others only request execution time segment 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 a call. If the appy time is valid, you can send a message to the window and vxds. If the appy time is invalid, you can only send a message to vxds.
_SHELL_SHELLEXECUTE is the corresponding function of the function shellexecute in Ring-3 in Ring-0. In fact, it calls the shellexecute in Ring-3 to complete this work. Using a shell service, you can run / open / print any files.
_SHELL_SHELLEXECUTE is defined as follows:
Vxdcall _shell_shellexecute,
It has only one parameter, the SHEXPACKET structure of the tablet address. It returns a value into EAX from the shellexecute function. Let us study the Shexpacket structure:
The byte number of the Shex_dwtotalsize Shexpacket structure adds an optional parameter RGCHBAGGAGE, which follows it directly after this structure. I will wait for Rgchbaggage.
The byte number of the Shex_dwtotalsize Shexpacket structure adds an optional parameter RGCHBAGGAGE, which follows it directly after this structure. I will wait for Rgchbaggage. The number of bytes of the shex_dwsize shexpacket structure does not include Rgchbaggage. In combination with the SHEX_DWTOTALSIZE value, the outer casing VxD can calculate the size of the RGCHBAGGAGE of any length. SHEX_IBOP you want to complete. If you specify 0, you want to open a file. If it is an executable file, run it. If you want to complete another action, you must specify the name of the action in RGCHBagGage, in which you must start from this Shexpacket structure to an ASCII string, this distance size is based on byte count, string designated The name of the operation you want to do. The SHEXPACKET structure is 32 bytes. If the operation string follows the Shexpacket structure, the value in the shex_ibop must be 32. To know what you can complete, check the Shellexecute service. There are three operations defined, "Open", "Print", and "Explore". Shex_ibfile starts from this structure to an ASCII string, this string is the file name you want to pass to SHELLEXECUTE, like Shex_iboP members. Shex_ibparams You want to pass optional parameters for files specified by shex_ibfile. If this file is a document file, you don't want to pass any parameters to it, use 0. If you want to pass parameters to that file, put the distance from this structure to the string specified by this member in this member. In short, just like shex_ibop and shex_ibfile members. Shex_ibdir work 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 put the distance value from this structure to the directory name string to this member. Shex_dwreserved is reserved if the name is referred to. Don't care about it. How to display the shex_ncmdshow application window. This is a value that you are passing to showwindow normally, for example, SW_XXXX value. These values can be viewed in Windows.inc. All members of all members are double words. Here I introduce the Rgchbaggage members I promised. Only one point is different, because its size is variable, so it does not include the definition of this structure as a SHEXPACKET structure. View shell.inc, you see that RGCHBagGage is not in the definition of the Shexpacket structure, although in the Windows 9x DDK document, it is declared a member of the Shexpacket structure.
What is RGCHBAGGAGE? Simply put it is a string array after following the Shexpacket structure. In this array, you can put the names, files you want to complete the file, you have to pass to the parameters of the file and the work directory. First get the distance between the first characters from the Shexpacket structure to the first characters of these strings (that is, some member values of this structure), plus these values with the flat panel of the Shexpacket structure, and shell vxd can get these strings. The offset in the RGCHBAGGAGE array. For example, if the Shexpacket structure begins with 60000h, the string is followed by the string, the distance between the structure and the string is the size of the structure itself, 32 bytes (20h). So the shell vxd knows the string positioned at 60020h.
example
This is an example of how to register how APPY TIME event and use _shell_shellexecute. VXD is dynamic and is used by a simple Win32 application. When a user presses "Run Calculator" button, Win32 application calls DeviceIoControl to request VXD to register an APPY TIME event and run in Calc.exe in the Windows directory. ; ------------------------------------------------- --------------------------------
Vxd Source Code
; ------------------------------------------------- --------------------------------
.386P
INCLUDE /MASM/INCLUDE / VMM.INC
INCLUDE /MASM/INCLUDE/vwin32.inc
INCLUDE /MASM/INCLUDE/SHELL.INC
VxDName Textequ
ControlName Textequ
Vxdmajorversion TextEqu <1>
VxdminorVersion TextEqu <0>
Vxd_static_data_seg
VXD_STATIC_DATA_ENDS
Vxd_locked_code_seg
; ------------------------------------------------- ---------------------------
; Remember: The name of the vxd must be uppercase else it Won't work / unload
; ------------------------------------------------- ---------------------------
Declare_virtual_device% vxdname,% vxdmajorversion,% vxdminorversion,% controlname, undefined_device_id, undefined_init_order
Begin_Control_Dispatch% vxdname
Control_Dispatch W32_Deviceiocontrol, ONDEviceIOCONTROL
END_CONTROL_DISPATCH% VXDNAME
Beginproc ONDEviceIOCONTROL
Assume ESI: PTR Diocparams
.IF [ESI] .dwioControlcode == 1
Vxdcall _shell_callatappytime, <
, 0, 0, 0>
.endif
XOR EAX, EAX
RET
Endproc ONDEVICEIOCONTROL
VXD_LOCKED_CODE_ENDS
Vxd_pageable_code_seg
BeginProc onappytime, ccall
Argvar Refdata, DWord
Argvar theflag, dword
Enterproc
Mov file.Shex_dwtotalsize, sizeof shexpacket
Add file.Shex_dwtotalsize, SizeOf Exename
Mov file.Shex_dwsize, sizeof shexpacket
Mov file.Shex_ibop, 0
Mov file.Shex_ibfile, Sizeof Shexpacket
Mov file.Shex_ibparams, 0
Mov file.Shex_ibdir, 0
Mov file.shex_dwreserved, 0mov file.Shex_ncmdshow, 1
Vxdcall _shell_shellexecute,
LeaveProc
Return
EndProc onappytime
VXD_PAGEABLE_CODE_ENDS
Vxd_pageable_data_seg
File Shexpacket <>
Exename DB "Calc.exe", 0
VXD_PAGEABLE_DATA_ENDS
end
explain
Vxd Waiting for a DeviceIocontrol message: No. 1 service. When it receives the above message, it will sign an appy Time event.
Vxdcall _shell_callatappytime, << offset32 onappytime>, 0, 0, 0>
It will transmit the tablet address of the onappytime function to _Shell_callatappytime, so that the shell vxd will call it when the appy time event occurs. Three parameters tight with the ONAppyTime function are 0 because we do not need to use any reference data and do not need to handle expiration.
When the APPY TIME event occurs, the shell vxd calls the ONAppyTIME function.
BeginProc onappytime, ccall
We describe a function with beginProc. Because Shell VXD calls ONAppyTime in the C call order, we need to specify the ccall property.
Argvar Refdata, Dwordargvar Theflag, DWordEnterProc ... LeaveProc Return
Because Shell VXD calls onAppyTime with two parameters, we must set the stack structure. The Argvar macro is used to adjust the stack structure of each parameter to be passed to the function. Its syntax is as follows:
Argvar Varname, Size, Used
Varname is the name of the parameter. You can use any of your favorite names. SIZE is the size of the parameter. You can use Byte, Word, DWORD, or 1, 2, 4. Used is usually ignored.
Follow the Argvar macro, we need to use EnterProc and LeaveProc macro to mark the beginning and end of the structure of the variable and parameters in the program, so that it can be accessed correctly. Use the Return macro to return to the caller.
Mov file.Shex_dwtotalsize, sizeof shexpacket
Add file.Shex_dwtotalsize, SizeOf Exename
Mov file.Shex_dwsize, sizeof shexpacket
Mov file.Shex_ibop, 0
Mov file.Shex_ibfile, Sizeof Shexpacket
Mov file.Shex_ibparams, 0
Mov file.Shex_ibdir, 0
Mov file.shex_dwreserved, 0
Mov file.Shex_ncmdshow, 1
Vxdcall _shell_shellexecute,
The instructions in this program are simple: initialize the ShexPacket structure and call _shell_shellexecute service. Remember shex_dwtotalsize contains the SHEXPACKET structure itself and combined with its string. This is a simple thing. If the string does not follow this structure, you must calculate the distance between the first byte from the structure to the last byte of the string. Shex_ibfile contains the size of this structure, because the program name is tight after this structure. Shex_ibdir is 0 that means the Windows directory as a working directory. This does not mean that the program must be in the Windows directory. The program can be anywhere you can find in WINDOWS.
Shex_ncmdshow is 1, that is, the value of SW_SHOWNORMAL.
File Shexpacket <> Exename DB "Calc.exe", 0
We define a shexpacket structure that follows the name of the program that wants to run.