⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vxd-e7.html

📁 汇编语言编写的虚拟驱动程序
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <meta name="Author" content="Iczelion">
   <meta name="GENERATOR" content="Mozilla/4.7 [en] (Win98; I) [Netscape]">
   <title>Application Time and Shell Functions</title>
</head>
<body text="#FFFFFF" bgcolor="#000080" link="#FFFF00" vlink="#8080FF" alink="#FF00FF">

<center>
<h1>
<font face="Tahoma"><font color="#FFFF99">Application Time and Shell Functions</font></font></h1></center>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>Download <a href="files/vxdexecute.zip">the
example</a>.</font></font></font>
<h3>
<b><font face="Tahoma"><font color="#FF99FF">Some Theory</font></font></b></h3>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>Application time
is usually called "appy time". It simply means the time when the system
VM is stable enough to allow interaction between VxDs and the ring-3 applications,
especially 16-bit ones. For example, at appy time, VxDs can load and call
functions in 16-bit DLLs. This appy time is not available under Windows
3.1x. Under Windows 3.1, a VxD can obtain the address of any function in
a 16-bit DLL and simulate a far call to that address. However, this will
interrupt whatever task the ring-3 program is doing resulting in VMM reentrancy.
So the only APIs which VxDs can call are those that are interrupt-safe,
i.e. PostMessage. Under Windows 95, a VxD can call almost any function
in any 16-bit DLL with the help of appy time.</font></font></font>
<br><font face="Tahoma"><font color="#FFFFFF"><font size=-1>Simply put,
if your VxD is notified that now is the appy time, it can load 16-bit DLLs
and call functions in them. So how does a VxD know that the appy time is
arrived?&nbsp; It must register an appy time event with the Shell VxD.
When the system VM is in a stable state, the Shell VxD will call the callback
function that the VxD specified when it registered for an appy time event.
Shell VxD will call your callback function only once for each registration
for appy time event. It's like applying for a job. You go to a recruiting
agency, register your name/telephone number with them. Then you go home.
When a job is available, the agency phones you about the good news. When
you acknowledge that news, they will never call you again.</font></font></font>
<br><font face="Tahoma"><font color="#FFFFFF"><font size=-1>It may take
some time before an appy time event is available. Appy time events are
not available under these circumstances:</font></font></font>
<ul>
<li>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>during system startup
and shutdown</font></font></font></li>

<li>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>when system VM
is in a critical section or waiting for a semaphore</font></font></font></li>
</ul>

<h3>
<font face="Tahoma"><font color="#FF99FF">Managing an appy time event</font></font></h3>
<font face="Tahoma"><font size=-1><font color="#FFFFFF">You can register
for an appy time event by calling on </font><b><font color="#FFFF99">_SHELL_CallAtAppyTime</font></b><font color="#FFFFFF">
which has the following definition:</font></font></font>
<blockquote><b><font face="Tahoma"><font color="#33FF33"><font size=-1>VxDCall
_SHELL_CallAtAppyTime, &lt;&lt;OFFSET32 pfnCallback>,&nbsp; dwRefData,
dwFlags, dwTimeout></font></font></font></b></blockquote>

<center><table BORDER CELLPADDING=5 WIDTH="79%" >
<tr>
<td><b><font face="Tahoma">pfnCallBack</font></b></td>

<td><font face="Tahoma"><font size=-1><font color="#FFFFFF">The flat address
of the callback function you want the Shell VxD to call when an appy time
event occurs. The function will receive two parameters, dwRefData and dwFlags
which are exactly identical to the two parameters you passed to </font><b><font color="#FFFF99">_SHELL_CallAtAppyTime</font></b><font color="#FFFFFF">.
Note that Shell VxD will call your callback function with C Calling sequence.
In short, you have to define your callback function like this:</font></font></font>
<p><font face="Tahoma"><font size=-1><b><font color="#FFCC33">BeginProc
</font></b><font color="#FFFFFF">OnAppyTime,
CCALL, PUBLIC</font></font></font>
<br><font face="Tahoma"><font size=-1><b><font color="#66FF99">ArgVar</font></b><font color="#FFFFFF">
dwRefData,DWORD&nbsp;&nbsp; ; declare argument name and type</font></font></font>
<br><font face="Tahoma"><font size=-1><b><font color="#66FF99">ArgVar </font></b><font color="#FFFFFF">dwFlags,
DWORD</font></font></font>
<br><b><font face="Tahoma"><font color="#FFFF99"><font size=-1>EnterProc</font></font></font></b>
<p><font face="Tahoma"><font color="#FFFFFF"><font size=-1>&lt;Your code
here></font></font></font>
<p><b><font face="Tahoma"><font color="#FFFF99"><font size=-1>LeaveProc</font></font></font></b>
<br><b><font face="Tahoma"><font color="#FF6666"><font size=-1>Return</font></font></font></b>
<br><font face="Tahoma"><font size=-1><b><font color="#FFCC33">EndProc
</font></b><font color="#FFFFFF">OnAppyTime</font></font></font></td>
</tr>

<tr>
<td><b><font face="Tahoma">dwRefData</font></b></td>

<td><font face="Tahoma"><font size=-1>Reference data you want Shell VxD
to pass to your callback function. It can be anything you want.</font></font></td>
</tr>

<tr>
<td><b><font face="Tahoma">dwFlags</font></b></td>

<td><font face="Tahoma"><font size=-1>Event flags. Can be one of the following
values:</font></font>
<blockquote><font face="Tahoma"><font size=-1><b><font color="#66FF99">CAAFL_RING0&nbsp;</font></b>
Ring zero event.</font></font>
<br><font face="Tahoma"><font size=-1><b><font color="#66FF99">CAAFL_TIMEOUT</font></b>&nbsp;
Time out the event after the duration specified by dwTimeout.&nbsp;</font></font></blockquote>
<font face="Tahoma"><font size=-1>&nbsp;Simply put, if you want to wait
for the appy time event for some period only, use <b><font color="#66FF99">CAAFL_TIMEOUT</font></b>
flag. If you want to wait indefinitely for the appy time event, use NULL.
I don't know what CAAFL_RING0 actually does.</font></font></td>
</tr>

<tr>
<td><b><font face="Tahoma">dwTimeout</font></b></td>

<td><font face="Tahoma"><font size=-1>The period of time the VxD wants
to wait for the appy time event to occur. I can't find any info about the
time unit used with this argument.&nbsp;</font></font></td>
</tr>
</table></center>

<p><font face="Tahoma"><font color="#FFFFFF"><font size=-1>This service
is asynchronous, meaning that it returns immediately after registering
your callback function for the appy time event.</font></font></font>
<br><font face="Tahoma"><font color="#FFFFFF"><font size=-1>If this service
call is successful, it returns the application time event handle in eax.
If it fails, eax contains 0.</font></font></font>
<br><font face="Tahoma"><font size=-1><font color="#FFFFFF">You can cancel
the appy time registration by calling on </font><b><font color="#FFFF99">_SHELL_CancelAppyTimeEvent</font></b><font color="#FFFFFF">
which takes only one parameter, the appy time event handle returned by
</font><b><font color="#FFFF99">_SHELL_CallAtAppyTime</font></b><font color="#FFFFFF">.</font></font></font>
<br><font face="Tahoma"><font size=-1><font color="#FFFFFF">To be on the
safe side, prior to calling </font><b><font color="#FFFF99">_SHELL_CallAtAppyTime</font></b><font color="#FFFFFF">,
you should check the system if appy time event will be available. For example,
what if you register for appy time event while the system is shutting down?
Your VxD's callback will never be called! You can query the system wheter
appy time event will be available by calling </font><b><font color="#FFFF99">_SHELL_QueryAppyTimeAvailable</font></b><font color="#FFFFFF">.
This service takes no parameter. It returns 0 in eax if appy time will
not be available, i.e. the system is closing down or the message server
got GP faults. This service doesn't tell you that <b>now</b> is the appy
time: it only tells you that there may be appy time events. In short, if
you want to play safe, call </font><b><font color="#FFFF99">_SHELL_QueryAppyTimeAvailable</font></b><font color="#FFFFFF">
first and if it returns a nonzero value in eax, you can proceed to call
</font><b><font color="#FFFF99">_SHELL_CallAtAppyTime</font></b><font color="#FFFFFF">.</font></font></font>
<h3>
<b><font face="Tahoma"><font color="#FF99FF">Application-time Shell Services</font></font></b></h3>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>When appy time
is reached, there are several Shell services you can call:</font></font></font>
<ul>
<li>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>_SHELL_CallDll</font></font></font></li>

<li>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>_SHELL_FreeLibrary</font></font></font></li>

<li>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>_SHELL_GetProcAddress</font></font></font></li>

<li>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>_SHELL_LoadLibrary</font></font></font></li>

<li>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>_SHELL_LocalAllocEx</font></font></font></li>

<li>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>_SHELL_LocalFree</font></font></font></li>
</ul>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>Those six services
are provided so VxDs can call 16-bit functions in 16-bit DLLs/ExE, such
as WinHelp. However, since we are moving on to the 32-bit world (and 64-bit,
in the future), I will not go into detail about them. If you're interested,
you can read about them in Windows 95/98 DDK documentation.</font></font></font>
<br><font face="Tahoma"><font size=-1><font color="#FFFFFF">There are other
application-time-only SHELL services which I think are more useful:</font><b><font color="#FFFF99">_SHELL_ShellExecute</font></b><font color="#FFFFFF">
and </font><b><font color="#FFFF99">_SHELL_BroadcastSystemMessage</font></b><font color="#FFFFFF">.
With </font><b><font color="#FFFF99">_SHELL_BroadcastSystemMessage</font></b><font color="#FFFFFF">,
you can send a message to all top-level windows and all VxDs in one call!
If the appy time is available, you can send messages to both windows and
VxDs. If the appy time is not available, you can send messages only to
VxDs.</font></font></font>
<br><font face="Tahoma"><font size=-1><b><font color="#FFFF99">_SHELL_ShellExecute</font></b><font color="#FFFFFF">
is the ring-0 counterpart of ShellExecute function in ring-3. Actually
it calls ring-3 ShellExecute to do the job. With this Shell service, you
can execute/open/print any file. </font><b><font color="#FFFF99">_SHELL_ShellExecute</font></b><font color="#FFFFFF">
has the following definition:</font></font></font>
<blockquote><b><font face="Tahoma"><font color="#66FF99"><font size=-1>VxDCall
_SHELL_ShellExecute, &lt;OFFSET32 ShexPacket></font></font></font></b></blockquote>
<font face="Tahoma"><font color="#FFFFFF"><font size=-1>It takes only one
parameter, the flat address of a SHEXPACKET structure. It returns the value
from ShellExecute in eax. Let's examine SHEXPACKET structure in detail
next.</font></font></font>
<br>&nbsp;
<center><table BORDER CELLPADDING=5 WIDTH="93%" >
<tr>
<td><b><font face="Tahoma">shex_dwTotalSize</font></b></td>

<td><font face="Tahoma"><font size=-1>The size in bytes of SHEXPACKET structure
plus the optional parameter, <b><font color="#FFFF99">rgchBaggage</font></b>,
which immediately follows this structure. I'll describe what <b><font color="#FFFF99">rgchBaggage</font></b>
shortly.</font></font></td>
</tr>

<tr>
<td><b><font face="Tahoma">shex_dwSize</font></b></td>

<td><font face="Tahoma"><font size=-1>The size in bytes of SHEXPACKET structure,
not counting <b><font color="#FFFF99">rgchBaggage</font></b>. Combined
with shex_dwTotalSize above, the SHELL VxD can calculate the size of rgchBaggage
which is of arbitrary length.</font></font></td>
</tr>

<tr>
<td><b><font face="Tahoma">shex_ibOp</font></b></td>

<td><font face="Tahoma"><font size=-1>The operation you want to perform.
If you specify 0, it means you want to open the file. If the file is an
executable one, it executes it. If you want to perform other operation,
you must specify the name of the operation somewhere in rgchBaggage and
this field must contain the distance in bytes from the start of this SHEXPACKET
structure to the first character of the ASCIIZ string that specifies the
name of the operation you want to perform. The size of SHEXPACKET is 32
bytes. If the operation string immediately follows the SHEXPACKET structure,
the value in shex_ibOp <b>MUST</b> be 32. As to the list of the operations
you can perform, check ShellExecute. There are three operations defined,
"open", "print" and "explore".</font></font></td>
</tr>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -