阅读:1139回复:2
哪位知道Ring0层的内核程序是如何启动Ring3的用户程序的?
NT下
帮帮菜鸟 |
|
沙发#
发布于:2004-11-30 12:53
http://www.osronline.com/article.cfm?id=94
|
|
板凳#
发布于:2004-11-30 21:31
Driver writers often ask whether or not a device driver can call a user-mode function. While the simple answer to this is that it isn’t possible, the inverted call model provides a mechanism that can be used to achieve similar functionality. Fortunately, this model is not only supported in the Windows OS architecture, it is used by existing operating system components!
The basic design of such a system consists of a service, a driver, and some protocol between the two. It works with monolithic drivers as well as layered drivers and only requires that the driver be able to receive device control operations (or their equivalent if you are using one of the driver library models). Figure 1 ― Simple Inverted Call Model Of course, exactly what these operations do depends upon the particular needs of your driver, but the basic mechanism needed is comparable: A queuing mechanism for requests that are awaiting responses from the service; A queuing mechanism for service threads awaiting requests to process; A protocol for describing the request to the service and matching up the service response with the original request; and Clean-up mechanism in case the request is cancelled or the service terminates prematurely The first part of this process relies upon one of the existing queue mechanisms, whether it is a linked list, a kernel queue object, or some other driver-invented process. The second requires a means of signaling between the service and the driver, whether it is using enqueued IRPs, dispatcher objects, completion ports, or some other driver developer favored mechanism. To demonstrate this technique we wrote what started out as a “simple” example. While the resulting example is not quite so simple it does demonstrate this basic technique and should allow developers to implement their own inverted-call mechanisms. In developing this example we focused on three key components: The “application” that reads and writes to the device; The “control service” that satisfies the inverted calls from the kernel driver; and The kernel driver that posts requests from the application to the control service and joins up the original request with the control service response The example is a data sink/data source example, where data is written from one (or more) applications and the control service links up the write and read operations. A few notes about this example: All code paths run at IRQL < DISPATCH_LEVEL; Data structures are stored in paged pool; No special queueing structure is used The example itself would not be a particularly useful driver since the service it provides is already available from the OS (and in far more efficient mechanisms). However, since the goal was to demonstrate an asynchronous inverted call implementation, our emphasis was on the implementation and not on the functionality of the driver. In the balance of this article we will describe the basic structure of the driver. The full source code for the example will be posted on the OSR web site. Driver Entry We chose to implement this driver using the legacy driver model. There is nothing inherent about this driver that requires it be a legacy driver, but because it is a software-only device it was a simpler model and appropriate for this example. Thus, as a legacy driver the DriverEntry function is responsible for creating the device objects that will be used by the driver. In our example we create two separate device objects, one is the control object, the other the data object. The control object is configured in such a way that it may only be opened once (“exclusive open”) while the data object allows concurrent read/write access to it. Each object type has a different device extension and device type. The driver distinguishes between the two devices based upon their device type and maintains two global points to each one. Having created the two devices and initialized the device extensions of each, the driver sets up its entry points and then returns success to the I/O Manager. The key data structures here are the device extensions. For the control device, there are two queues |
|
|