340 lines
8.2 KiB
C
340 lines
8.2 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 2000 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
headless.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This is the miniport driver for the hardware with no graphic adapter.
|
|||
|
Should work only with display driver for headless environment.
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
kernel mode only
|
|||
|
|
|||
|
Notes:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "dderror.h"
|
|||
|
#include "devioctl.h"
|
|||
|
#include "miniport.h"
|
|||
|
|
|||
|
#include "ntddvdeo.h"
|
|||
|
#include "video.h"
|
|||
|
#include "headless.h"
|
|||
|
|
|||
|
#if defined(ALLOC_PRAGMA)
|
|||
|
#pragma alloc_text(PAGE,DriverEntry)
|
|||
|
#pragma alloc_text(PAGE,HeadlessFindAdapter)
|
|||
|
#pragma alloc_text(PAGE,HeadlessInitialize)
|
|||
|
#pragma alloc_text(PAGE,HeadlessStartIO)
|
|||
|
#endif
|
|||
|
|
|||
|
ULONG
|
|||
|
DriverEntry(
|
|||
|
PVOID Context1,
|
|||
|
PVOID Context2
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Installable driver initialization entry point.
|
|||
|
This entry point is called directly by the I/O system.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Context1 - First context value passed by the operating system. This is
|
|||
|
the value with which the miniport driver calls VideoPortInitialize().
|
|||
|
|
|||
|
Context2 - Second context value passed by the operating system. This is
|
|||
|
the value with which the miniport driver calls VideoPortInitialize().
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Status from VideoPortInitialize()
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
VIDEO_HW_INITIALIZATION_DATA hwInitData;
|
|||
|
ULONG initializationStatus;
|
|||
|
|
|||
|
//
|
|||
|
// Zero out structure.
|
|||
|
//
|
|||
|
|
|||
|
VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
|
|||
|
|
|||
|
hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
|
|||
|
|
|||
|
//
|
|||
|
// Set entry points.
|
|||
|
//
|
|||
|
|
|||
|
hwInitData.HwFindAdapter = HeadlessFindAdapter;
|
|||
|
hwInitData.HwInitialize = HeadlessInitialize;
|
|||
|
hwInitData.HwStartIO = HeadlessStartIO;
|
|||
|
|
|||
|
hwInitData.AdapterInterfaceType = PCIBus;
|
|||
|
|
|||
|
initializationStatus = VideoPortInitialize(Context1,
|
|||
|
Context2,
|
|||
|
&hwInitData,
|
|||
|
NULL);
|
|||
|
|
|||
|
return initializationStatus;
|
|||
|
}
|
|||
|
|
|||
|
VP_STATUS
|
|||
|
HeadlessFindAdapter(
|
|||
|
PVOID HwDeviceExtension,
|
|||
|
PVOID HwContext,
|
|||
|
PWSTR ArgumentString,
|
|||
|
PVIDEO_PORT_CONFIG_INFO ConfigInfo,
|
|||
|
PUCHAR Again
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is called to determine if the adapter for this driver
|
|||
|
is present in the system.
|
|||
|
If it is present, the function fills out some information describing
|
|||
|
the adapter.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Supplies the miniport driver's adapter storage. This
|
|||
|
storage is initialized to zero before this call.
|
|||
|
|
|||
|
HwContext - Supplies the context value which was passed to
|
|||
|
VideoPortInitialize().
|
|||
|
|
|||
|
ArgumentString - Supplies a NULL terminated ASCII string. This string
|
|||
|
originates from the user.
|
|||
|
|
|||
|
ConfigInfo - Returns the configuration information structure which is
|
|||
|
filled by the miniport driver. This structure is initialized with
|
|||
|
any known configuration information (such as SystemIoBusNumber) by
|
|||
|
the port driver. Where possible, drivers should have one set of
|
|||
|
defaults which do not require any supplied configuration information.
|
|||
|
|
|||
|
Again - Indicates if the miniport driver wants the port driver to call
|
|||
|
its VIDEO_HW_FIND_ADAPTER function again with a new device extension
|
|||
|
and the same config info. This is used by the miniport drivers which
|
|||
|
can search for several adapters on a bus.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
This routine must return:
|
|||
|
|
|||
|
NO_ERROR - Indicates a host adapter was found and the
|
|||
|
configuration information was successfully determined.
|
|||
|
|
|||
|
ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
|
|||
|
error obtaining the configuration information. If possible an error
|
|||
|
should be logged.
|
|||
|
|
|||
|
ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
|
|||
|
supplied configuration information.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
VP_STATUS status;
|
|||
|
PHYSICAL_ADDRESS Zero = { 0, 0 };
|
|||
|
VIDEO_PORT_HEADLESS_INTERFACE HeadlessInterface;
|
|||
|
|
|||
|
VideoDebugPrint((2, "Headless - FindAdapter\n"));
|
|||
|
|
|||
|
//
|
|||
|
// Make sure the size of the structure is at least as large as what we
|
|||
|
// are expecting (check version of the config info structure).
|
|||
|
//
|
|||
|
|
|||
|
if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) {
|
|||
|
|
|||
|
return ERROR_INVALID_PARAMETER;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// We only want this driver to load if no other video miniports
|
|||
|
// loaded successfully.
|
|||
|
//
|
|||
|
|
|||
|
HeadlessInterface.Size = sizeof(VIDEO_PORT_HEADLESS_INTERFACE);
|
|||
|
HeadlessInterface.Version = 1;
|
|||
|
|
|||
|
status = VideoPortQueryServices(
|
|||
|
HwDeviceExtension,
|
|||
|
VideoPortServicesHeadless,
|
|||
|
(PINTERFACE)&HeadlessInterface);
|
|||
|
|
|||
|
if (status == NO_ERROR) {
|
|||
|
|
|||
|
ULONG DisplayDeviceCount;
|
|||
|
|
|||
|
HeadlessInterface.InterfaceReference(HeadlessInterface.Context);
|
|||
|
|
|||
|
DisplayDeviceCount =
|
|||
|
HeadlessInterface.HeadlessGetDeviceCount(HwDeviceExtension);
|
|||
|
|
|||
|
HeadlessInterface.InterfaceDereference(HeadlessInterface.Context);
|
|||
|
|
|||
|
if (DisplayDeviceCount != 0) {
|
|||
|
|
|||
|
return ERROR_DEV_NOT_EXIST;
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
return ERROR_INVALID_PARAMETER;
|
|||
|
}
|
|||
|
|
|||
|
ConfigInfo->NumEmulatorAccessEntries = 0;
|
|||
|
ConfigInfo->EmulatorAccessEntries = NULL;
|
|||
|
ConfigInfo->EmulatorAccessEntriesContext = 0;
|
|||
|
|
|||
|
ConfigInfo->VdmPhysicalVideoMemoryAddress = Zero;
|
|||
|
ConfigInfo->VdmPhysicalVideoMemoryLength = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Minimum size of the buffer required to store the hardware state
|
|||
|
// information returned by IOCTL_VIDEO_SAVE_HARDWARE_STATE.
|
|||
|
//
|
|||
|
|
|||
|
ConfigInfo->HardwareStateSize = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Indicate we do not wish to be called again for another initialization.
|
|||
|
//
|
|||
|
|
|||
|
*Again = 0;
|
|||
|
|
|||
|
return NO_ERROR;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
HeadlessInitialize(
|
|||
|
PVOID HwDeviceExtension
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine does one time initialization of the device.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Pointer to the miniport driver's adapter information.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
VideoDebugPrint((2, "Headless - Initialize\n"));
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
HeadlessStartIO(
|
|||
|
PVOID HwDeviceExtension,
|
|||
|
PVIDEO_REQUEST_PACKET RequestPacket
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is the main execution routine for the miniport driver. It
|
|||
|
acceptss a Video Request Packet, performs the request, and then returns
|
|||
|
with the appropriate status.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
HwDeviceExtension - Pointer to the miniport driver's adapter information.
|
|||
|
|
|||
|
RequestPacket - Pointer to the video request packet. This structure
|
|||
|
contains all the parameters passed to the VideoIoControl function.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
This routine will return error codes from the various support routines
|
|||
|
and will also return ERROR_INSUFFICIENT_BUFFER for incorrectly sized
|
|||
|
buffers and ERROR_INVALID_FUNCTION for unsupported functions.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
VP_STATUS status;
|
|||
|
|
|||
|
//
|
|||
|
// Switch on the IoContolCode in the RequestPacket. It indicates which
|
|||
|
// function must be performed by the driver.
|
|||
|
//
|
|||
|
|
|||
|
switch (RequestPacket->IoControlCode) {
|
|||
|
|
|||
|
case IOCTL_VIDEO_QUERY_AVAIL_MODES:
|
|||
|
|
|||
|
VideoDebugPrint((2, "HeadlessStartIO - QueryAvailableModes\n"));
|
|||
|
|
|||
|
status = HeadlessQueryAvailableModes(
|
|||
|
(PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer,
|
|||
|
RequestPacket->OutputBufferLength,
|
|||
|
(PULONG)(&RequestPacket->StatusBlock->Information));
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
|
|||
|
|
|||
|
VideoDebugPrint((2, "HeadlessStartIO - QueryNumAvailableModes\n"));
|
|||
|
|
|||
|
status = HeadlessQueryNumberOfAvailableModes(
|
|||
|
(PVIDEO_NUM_MODES) RequestPacket->OutputBuffer,
|
|||
|
RequestPacket->OutputBufferLength,
|
|||
|
(PULONG)(&RequestPacket->StatusBlock->Information));
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case IOCTL_VIDEO_RESET_DEVICE:
|
|||
|
|
|||
|
VideoDebugPrint((2, "HeadlessStartIO - Got reset, perhaps for dummy device\n"));
|
|||
|
status = NO_ERROR;
|
|||
|
break;
|
|||
|
|
|||
|
//
|
|||
|
// if we get here, an invalid IoControlCode was specified.
|
|||
|
//
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
VideoDebugPrint((1, "Fell through headless startIO routine - invalid command 0x%08X\n", RequestPacket->IoControlCode));
|
|||
|
|
|||
|
status = ERROR_INVALID_FUNCTION;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
RequestPacket->StatusBlock->Status = status;
|
|||
|
|
|||
|
return TRUE;
|
|||
|
|
|||
|
}
|