|
|
Microsoft Windows NT Build 511 (DDK SDK) 11-01-1993
/******************************Module*Header*******************************\
* Module Name: enable.c
*
* Functions to enable and disable the driver
*
* Copyright (c) 1992 Microsoft Corporation
\**************************************************************************/
#include "driver.h"
#include "winperf.h" // for Performance API strucuture definitions (PERFCTR)
PPERF_COUNTER_BLOCK pCounterBlock; // data structure for counter values (PERFCTR)
FLONG gflDrv = 0;
#ifdef FIREWALLS
LONG cPDEV = 0; // PDEV counter for checking Engine
#endif
extern GDIINFO gaulCap; // in gdiinfo.c
extern LOGPALETTE logPalVGA; // in gdiinfo.c
extern BYTE gaajPat[19][32]; // in gdiinfo.c
extern DEVINFO devinfoVGA; // in gdiinfo.c
extern LPBYTE pPtrSave;
BOOL SetUpBanking(PDEVSURF, PPDEV);
BOOL bInitPointer(PPDEV);
extern ajConvertBuffer[1]; // Arbitrary sized array!
static DRVFN gadrvfn[] = {
{ INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV },
{ INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV },
{ INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV },
{ INDEX_DrvEnableSurface, (PFN) DrvEnableSurface },
{ INDEX_DrvDisableSurface, (PFN) DrvDisableSurface },
{ INDEX_DrvRealizeBrush, (PFN) DrvRealizeBrush },
{ INDEX_DrvBitBlt, (PFN) DrvBitBlt },
{ INDEX_DrvTextOut, (PFN) DrvTextOut },
{ INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape },
{ INDEX_DrvMovePointer, (PFN) DrvMovePointer },
{ INDEX_DrvStrokePath, (PFN) DrvStrokePath },
{ INDEX_DrvCopyBits, (PFN) DrvCopyBits },
{ INDEX_DrvDitherColor, (PFN) DrvDitherColor },
{ INDEX_DrvAssertMode, (PFN) DrvAssertMode },
{ INDEX_DrvSaveScreenBits, (PFN) DrvSaveScreenBits },
{ INDEX_DrvGetModes, (PFN) DrvGetModes },
{ INDEX_DrvFillPath, (PFN) DrvFillPath },
{ INDEX_DrvPaint, (PFN) DrvPaint }
};
/******************************Public*Routine******************************\
* BOOL bInitProc(HMODULE hmod)
*
* DLL initialization procedure. Save the module handle and exit.
*
* This routine creates a named mapped memory section that is used
* to communicate the driver's performance data to the extensible counter
* DLL. This method will only work with "user" mode driver DLL's.
* Kernel or privileged drivers need to provide an IOCTL interface that
* will communicate the performance data to the extensible counter DLL.
*
\**************************************************************************/
BOOL bInitProc(HMODULE hmod, ULONG Reason, LPVOID Reserved)
{
HANDLE hMappedObject;
TCHAR szMappedObjectName[] = TEXT("VGA_COUNTER_BLOCK");
if (Reason == DLL_PROCESS_ATTACH)
{
//
// create named section for the performance data
//
hMappedObject = CreateFileMapping((HANDLE)0xFFFFFFFF,
NULL,
PAGE_READWRITE,
0,
4096,
szMappedObjectName);
if (hMappedObject == NULL)
{
// Should put out an EventLog error message here
DISPDBG((0, "VGA: Could not Create Mapped Object for Counters %x",
GetLastError()));
pCounterBlock = NULL;
}
else
{
// Mapped object created okay
//
// map the section and assign the counter block pointer
// to this section of memory
//
pCounterBlock = (PPERF_COUNTER_BLOCK)
MapViewOfFile(hMappedObject,
FILE_MAP_ALL_ACCESS,
0,
0,
0);
if (pCounterBlock == NULL)
{
// Failed to Map View of file
DISPDBG((0, "VGA: Failed to Map View of File %x",
GetLastError()));
}
}
}
return(TRUE);
Reserved=Reserved;
}
/******************************Public*Routine******************************\
* BOOL bEnableDriver(iEngineVersion, cb, pded)
*
* Enables the driver by filling the function table. This call is made by
* the Engine to fill its driver function table in the LDEV (Logical DEVice).
* This call should only be made once per driver but we can handle being
* called multiple times.
*
\**************************************************************************/
BOOL DrvEnableDriver
(
ULONG iEngineVersion,
ULONG cb,
PDRVENABLEDATA pded
)
{
DISPDBG((2, "VGA: enabling Driver\n"));
cb /= sizeof(ULONG);
switch(cb)
{
case 3:
pded->pdrvfn = gadrvfn;
case 2:
pded->c = sizeof(gadrvfn) / sizeof(DRVFN);
case 1:
pded->iDriverVersion = DDI_DRIVER_VERSION;
}
return(TRUE);
}
/******************************Public*Routine******************************\
* VOID vDisableDriver
*
* Unload the driver and any data in may have created.
*
\**************************************************************************/
VOID DrvDisableDriver()
{
DISPDBG((2, "VGA: disabling Driver\n"));
}
/******************************Public*Routine******************************\
* BOOL bLoadResources()
*
* Load the resources used by the PDEV
*
\**************************************************************************/
BOOL bLoadResources(PPDEV ppdev)
{
// Load the font resources
return(TRUE);
UNREFERENCED_PARAMETER(ppdev);
}
/******************************Public*Routine******************************\
* bInitDefaultPatterns
*
* Creates the default monochrome patterns to be used on it's surface.
*
\**************************************************************************/
BOOL bInitDefaultPatterns(PPDEV ppdev)
{
SIZEL sizl;
INT iLoop;
PULONG pulInit;
sizl.cx = 8;
sizl.cy = 8;
DISPDBG((2, "VGA: initializing defailt patterns\n"));
for (iLoop = 0; iLoop < HS_DDI_MAX; iLoop++)
{
pulInit = (PULONG) (&gaajPat[iLoop][0]);
ppdev->ahbmPat[iLoop] = EngCreateBitmap(sizl, sizl.cx / 8, BMF_1BPP,
BMF_TOPDOWN, pulInit);
if (ppdev->ahbmPat[iLoop] == (HBITMAP)0)
{
// Release any bitmaps we have created.
while(iLoop--)
EngDeleteSurface((HSURF) ppdev->ahbmPat[iLoop]);
return(FALSE);
}
}
return(TRUE);
}
/******************************Public*Routine******************************\
* DHPDEV DrvEnablePDEV
*
* Enable the Physical DEVice
*
* Warnings:
* The PDEV isn't complete until bCompletePDEV is called.
*
\**************************************************************************/
DHPDEV DrvEnablePDEV
(
DEVMODEW *pdrivw,
PWSTR pwszLogAddress,
ULONG cPatterns,
PHSURF ahsurfPatterns,
ULONG cjGdiInfo,
ULONG *pdevcaps,
ULONG cb,
PDEVINFO pdevinfo,
PWSTR pwszDataFile,
PWSTR pwszDeviceName,
HANDLE hDriver // Handle to base driver
)
{
FLONG fl = 0;
DHPDEV dhpdev = (DHPDEV) 0;
PPDEV ppdev;
SYSTEM_INFO SystemInfo;
DISPDBG((2, "VGA: enabling PDEV\n"));
// Define flag to keep track of allocation
#define PDEV_ALLOCED 0x01
#ifdef DRV_ONE_PDEV
if (gflDrv & DRV_ENABLED_PDEV)
{
// SAVE_ERROR_CODE(DDI_PDEV_ALREADY_ENABLED);
goto error;
}
#endif
dhpdev = (DHPDEV) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(PDEV));
if (dhpdev == (DHPDEV) 0)
goto error;
fl |= PDEV_ALLOCED;
ppdev = (PPDEV) dhpdev;
// Identifier, for debugging purposes
ppdev->ident = PDEV_IDENT;
// Determine whether this is a 386 or a better processor
GetSystemInfo(&SystemInfo);
if (SystemInfo.dwProcessorType == PROCESSOR_INTEL_386) {
ppdev->ulIs386 = 1;
} else {
ppdev->ulIs386 = 0;
}
// Cache the device driver handle away for later use.
ppdev->hDriver = hDriver;
// Initialize the cursor stuff. We can violate the atomic rule here
// since nobody can talk to the driver yet.
ppdev->xyCursor.x = 320; // Non-atomic
ppdev->xyCursor.y = 240; // Non-atomic
ppdev->ptlExtent.x = 0;
ppdev->ptlExtent.y = 0;
ppdev->cExtent = 0;
ppdev->flCursor = CURSOR_DOWN;
//
// Get the current screen mode information. Set up device caps and devinfo.
//
if (!bInitPDEV(ppdev, pdrivw, &gaulCap, &devinfoVGA))
{
DISPDBG((1, "DISP VGA DrvEnablePDEV failed bInitPDEV\n"));
goto error;
}
if (!bLoadResources(ppdev))
goto error;
if (!bInitDefaultPatterns(ppdev))
goto error;
#ifdef DRV_ONE_PDEV
gflDrv |= DRV_ENABLED_PDEV; // So we're not called twice
#endif
cPatterns=min(cPatterns, HS_DDI_MAX);
memcpy((PVOID)ahsurfPatterns, ppdev->ahbmPat, cPatterns*sizeof(HBITMAP));
cjGdiInfo=min(cjGdiInfo, sizeof(GDIINFO));
memcpy(pdevcaps, &gaulCap, cjGdiInfo);
// Now let's pass back the devinfo
devinfoVGA.hpalDefault = EngCreatePalette(PAL_INDEXED, 16,
(PULONG) (logPalVGA.palPalEntry),
0, 0, 0);
// *pdevinfo = devinfoVGA;
memcpy((PVOID) pdevinfo, (PVOID) &devinfoVGA, (ULONG) sizeof(DEVINFO));
// Try to preallocate a saved screen bits buffer. If we fail, set the flag
// to indicate the buffer is in use, so that we'll never attempt to use it.
// If we succeed, mark the buffer as free.
if ((ppdev->pjPreallocSSBBuffer = (PUCHAR)
LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, PREALLOC_SSB_SIZE))
!= NULL) {
ppdev->flPreallocSSBBufferInUse = FALSE;
ppdev->ulPreallocSSBSize = PREALLOC_SSB_SIZE;
} else {
ppdev->flPreallocSSBBufferInUse = TRUE;
}
// Fill in the DIB4->VGA conversion tables. Allow 256 extra bytes so that
// we can always safely align the tables to a 256-byte boundary, for
// look-up reasons. There are four tables, each 256 bytes long
ppdev->pucDIB4ToVGAConvBuffer =
(UCHAR *) LocalAlloc((LMEM_FIXED | LMEM_ZEROINIT),
((256*4+256)*sizeof(UCHAR)));
if (ppdev->pucDIB4ToVGAConvBuffer == NULL) {
goto error;
}
// Round the table start up to the nearest 256 byte boundary, because the
// tables must start on 256-byte boundaries for look-up reasons
ppdev->pucDIB4ToVGAConvTables =
(UCHAR *) ((ULONG) (ppdev->pucDIB4ToVGAConvBuffer + 0xFF) & ~0xFF);
vSetDIB4ToVGATables(ppdev->pucDIB4ToVGAConvTables);
return(dhpdev);
error:
if (fl & PDEV_ALLOCED)
LocalFree(dhpdev);
return((DHPDEV) 0);
UNREFERENCED_PARAMETER(cb);
UNREFERENCED_PARAMETER(pwszLogAddress);
UNREFERENCED_PARAMETER(pwszDataFile);
UNREFERENCED_PARAMETER(pwszDeviceName);
}
/******************************Public*Routine******************************\
* BOOL bCompletePDEV(dhpdev, hpdev)
*
* Complete the initialization of the PDEV
*
\**************************************************************************/
VOID DrvCompletePDEV(
DHPDEV dhpdev,
HDEV hdev)
{
PPDEV ppdev;
ppdev = (PPDEV) dhpdev;
ppdev->hdevEng = hdev;
}
/******************************Public*Routine******************************\
* VOID vFreeResources(ppdev)
*
* Free the resources used by the PDEV
*
* Effects:
*
* Warnings:
*
\**************************************************************************/
VOID vFreeResources(PPDEV ppdev)
{
UNREFERENCED_PARAMETER(ppdev);
}
/******************************Public*Routine******************************\
* VOID vKillPatterns(ppdev)
*
* Clear the standard patterns
*
\**************************************************************************/
VOID vKillPatterns(PPDEV ppdev)
{
INT ii;
for (ii = 0; ii < HS_DDI_MAX; ii++)
EngDeleteSurface((HSURF) ppdev->ahbmPat[ii]);
}
/******************************Public*Routine******************************\
* VOID DrvDisablePDEV(dhpdev)
*
* Shutdown this physical device.
*
* Warnings:
* If a surface is still active for this PDEV it will be freed.
*
\**************************************************************************/
VOID DrvDisablePDEV(DHPDEV dhpdev)
{
PPDEV ppdev;
ppdev = (PPDEV) dhpdev;
DISPDBG((2, "VGA:disabling PDEV\n"));
// ASSERT(ppdev != (PPDEV) NULL, "PDEV error");
// Is there a deliquent surface still in the PDEV?
if (ppdev->hsurfEng != (HSURF) 0)
DrvDisableSurface(dhpdev);
// Check if the Engine has called us to many times.
// ASSERT(--cPDEV >= 0, "PDEV - too many disables");
// Free the resources and bitmaps associated with this PDEV
vFreeResources(ppdev);
vKillPatterns(ppdev);
// Free the preallocated saved screen bits buffer, if there is one.
if (ppdev->pjPreallocSSBBuffer != NULL) {
LocalFree(ppdev->pjPreallocSSBBuffer);
}
// Free the conversion table buffer
if (ppdev->pucDIB4ToVGAConvBuffer != NULL) {
LocalFree(ppdev->pucDIB4ToVGAConvBuffer);
}
// Delete the PDEV
LocalFree(dhpdev);
DISPDBG((2, "VGA: disabled PDEV\n"));
#ifdef DRV_ONE_PDEV
gflDrv &= ~DRV_ENABLED_PDEV;
#endif
}
/******************************Public*Routine******************************\
* HSURF DrvEnableSurface(dhpdev)
*
* Enable the surface for the device. This will actually intialize the
* screen on the VGA.
*
* Warnings:
* This routine should only be called ONCE per PDEV.
*
\**************************************************************************/
HSURF DrvEnableSurface(DHPDEV dhpdev)
{
PPDEV ppdev;
PDEVSURF pdsurf;
DHSURF dhsurf;
HSURF hsurf;
DISPDBG((2, "VGA:enabling Surface\n"));
ppdev = (PPDEV) dhpdev;
//
// Initialize the VGA device into the selected mode which will also map
// the video frame buffer
//
if (!bInitVGA(ppdev, TRUE))
{
goto error_done;
}
dhsurf = (DHSURF) LocalAlloc(LMEM_FIXED, (SIZE_T) sizeof(DEVSURF));
if (dhsurf == (DHSURF) 0)
goto error_done;
pdsurf = (PDEVSURF) dhsurf;
pdsurf->ident = DEVSURF_IDENT;
pdsurf->flSurf = 0;
pdsurf->iFormat = BMF_PHYSDEVICE;
pdsurf->jReserved1 = 0;
pdsurf->jReserved2 = 0;
pdsurf->ppdev = ppdev;
pdsurf->sizlSurf.cx = ppdev->sizlSurf.cx;
pdsurf->sizlSurf.cy = ppdev->sizlSurf.cy;
pdsurf->lNextPlane = 0;
pdsurf->pvScan0 = ppdev->pjScreen;
pdsurf->pvBitmapStart = ppdev->pjScreen;
pdsurf->pvStart = ppdev->pjScreen;
pdsurf->pvConv = &ajConvertBuffer[0];
if (!bInitPointer(ppdev)) {
DISPDBG((0, "VGA DrvEnablePDEV failed bInitPointer\n"));
goto error_clean;
}
if (!SetUpBanking(pdsurf, ppdev)) {
DISPDBG((0, "VGA DrvEnablePDEV failed SetUpBanking\n"));
goto error_clean;
}
// Initialize pointer information.
if ((hsurf = EngCreateSurface(dhsurf, ppdev->sizlSurf)) == (HSURF) 0)
{
DISPDBG((0, "VGA DrvEnablePDEV failed EngCreateSurface\n"));
goto error_clean;
}
if (EngAssociateSurface(hsurf, ppdev->hdevEng,
HOOK_BITBLT | HOOK_TEXTOUT | HOOK_STROKEPATH |
HOOK_COPYBITS | HOOK_PAINT | HOOK_FILLPATH))
{
ppdev->hsurfEng = hsurf;
ppdev->pdsurf = pdsurf;
// Set up an empty saved screen block list
pdsurf->ssbList = NULL;
// Initialize the offscreen adapter memory heap to currently all
// available
// Beginning of heap starts right after the displayed bitmap ends
pdsurf->pjAdapterHeapStart = ((PBYTE)pdsurf->pvBitmapStart) +
(pdsurf->lNextScan * pdsurf->sizlSurf.cy);
// End of heap is the start of either the pointer work area or the
// hardware pointer reserved memory area, whichever comes first
pdsurf->pjAdapterHeapEnd = pPtrSave;
if (ppdev->pPointerAttributes != NULL)
{
// There's a hardware pointer, so check what display memory it
// uses, if any
if (ppdev->PointerCapabilities.HWPtrBitmapStart != -1)
{
// The hardware pointer does use display memory
if (( ((PBYTE)pdsurf->pvBitmapStart) +
ppdev->PointerCapabilities.HWPtrBitmapStart) <
pdsurf->pjAdapterHeapEnd)
{
// The hardware pointer marks the end of the heap
pdsurf->pjAdapterHeapEnd = ((PBYTE)pdsurf->pvBitmapStart) +
ppdev->PointerCapabilities.HWPtrBitmapStart;
}
}
}
// The current top of the heap is the end of the heap, because the heap
// is empty
pdsurf->pjAdapterHeapTop = pdsurf->pjAdapterHeapEnd;
DISPDBG((2, "VGA: enabled surface\n"));
return(hsurf);
}
DISPDBG((0, "VGA DrvEnablePDEV failed EngDeleteSurface\n"));
EngDeleteSurface(hsurf);
error_clean:
// We created the surface, so delete it
LocalFree(dhsurf);
error_done:
return((HSURF) 0);
}
/******************************Public*Routine******************************\
* DrvDisableSurface
*
* Free resources associated with this surface.
*
\**************************************************************************/
VOID DrvDisableSurface(DHPDEV dhpdev)
{
PPDEV ppdev = (PPDEV) dhpdev;
PDEVSURF pdsurf = ppdev->pdsurf;
PSAVED_SCREEN_BITS pSSB, pSSBNext;
DISPDBG((2, "VGA:disabling surface\n"));
// Free up banking-related stuff.
LocalFree(pdsurf->pBankSelectInfo);
if (pdsurf->pbiBankInfo != NULL) {
LocalFree(pdsurf->pbiBankInfo);
}
if (pdsurf->pbiBankInfo2RW != NULL) {
LocalFree(pdsurf->pbiBankInfo2RW);
}
if (pdsurf->pvBankBufferPlane0 != NULL) {
LocalFree(pdsurf->pvBankBufferPlane0);
}
if (ppdev->pPointerAttributes != NULL) {
LocalFree(ppdev->pPointerAttributes);
}
// Free any pending saved screen bit blocks.
pSSB = pdsurf->ssbList;
while (pSSB != (PSAVED_SCREEN_BITS) NULL) {
// Point to the next saved screen bits block
pSSBNext = (PSAVED_SCREEN_BITS) pSSB->pvNextSSB;
// Free the current block
LocalFree(pSSB);
pSSB = pSSBNext;
}
EngDeleteSurface((HSURF) ppdev->hsurfEng);
LocalFree(pdsurf); // free the surface
DISPDBG((2, "VGA:disabled surface\n"));
}
/******************************Public*Routine******************************\
* DrvAssertMode
*
* Ping the device back into its last known mode
*
\**************************************************************************/
VOID DrvAssertMode(DHPDEV dhpdev, BOOL Enable)
{
PPDEV ppdev = (PPDEV) dhpdev;
ULONG returnedDataLength;
DISPDBG((2, "VGA: DrvAssertMode\n"));
if (Enable) {
//
// The screen must be reenabled since we had gone to full screen.
// Re-initialize the device.
// !!! BUGBUG what happens if this fails ??
//
bInitVGA(ppdev, FALSE);
vForceBank0(ppdev);
} else {
//
// We must give up the display.
// Call the kernel driver to reset the device to a known state.
//
if (!DeviceIoControl(ppdev->hDriver,
IOCTL_VIDEO_RESET_DEVICE,
NULL,
0,
NULL,
0,
&returnedDataLength,
NULL)) {
RIP("VGA.DLL: Reset Device Failed");
}
}
return;
}
/******************************Public*Routine******************************\
* DrvGetModes
*
* Returns the list of available modes for the device.
*
\**************************************************************************/
ULONG DrvGetModes(
HANDLE hDriver,
ULONG cjSize,
DEVMODEW *pdm)
{
DWORD cModes;
DWORD cbOutputSize;
PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp;
DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
DWORD cbModeSize;
DISPDBG((2, "Vga.dll:DrvGetModes\n"));
cModes = getAvailableModes(hDriver,
(PVIDEO_MODE_INFORMATION *) &pVideoModeInformation,
&cbModeSize);
if (cModes == 0)
{
DISPDBG((0, "VGA DISP DrvGetModes failed to get mode information"));
return 0;
}
if (pdm == NULL)
{
cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
}
else
{
//
// Now copy the information for the supported modes back into the output
// buffer
//
cbOutputSize = 0;
pVideoTemp = pVideoModeInformation;
do
{
if (pVideoTemp->Length != 0)
{
if (cOutputModes == 0)
{
break;
}
//
// Zero the entire structure to start off with.
//
memset(pdm, 0, sizeof(DEVMODEW));
//
// Set the name of the device to the name of the DLL.
//
memcpy(&(pdm->dmDeviceName), L"vga", sizeof(L"vga"));
pdm->dmSpecVersion = DM_SPECVERSION;
pdm->dmDriverVersion = DM_SPECVERSION;
//
// We currently do not support Extra information in the driver
//
pdm->dmDriverExtra = DRIVER_EXTRA_SIZE;
pdm->dmSize = sizeof(DEVMODEW);
pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes *
pVideoTemp->BitsPerPlane;
pdm->dmPelsWidth = pVideoTemp->VisScreenWidth;
pdm->dmPelsHeight = pVideoTemp->VisScreenHeight;
pdm->dmDisplayFrequency = pVideoTemp->Frequency;
if (pVideoTemp->AttributeFlags & VIDEO_MODE_INTERLACED)
{
pdm->dmDisplayFlags |= DM_INTERLACED;
}
//
// Go to the next DEVMODE entry in the buffer.
//
cOutputModes--;
pdm = (LPDEVMODEW) ( ((ULONG)pdm) + sizeof(DEVMODEW) +
DRIVER_EXTRA_SIZE);
cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE);
}
pVideoTemp = (PVIDEO_MODE_INFORMATION)
(((PUCHAR)pVideoTemp) + cbModeSize);
} while (--cModes);
}
LocalFree(pVideoModeInformation);
return cbOutputSize;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.