mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
671 lines
15 KiB
671 lines
15 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: enable.c
|
|
*
|
|
* Test installable font driver.
|
|
*
|
|
* This file contains the code for a simple installable font driver. The
|
|
* driver itself doesn't support any font file format or supply any glyphs.
|
|
* This is okay since it's purpose is really to test that installable font
|
|
* driver loading code works, that installable drivers get called with
|
|
* DrvLoadFont, and that the DrvNamedEscape functionality works.
|
|
*
|
|
* Created: 1-Mar-1996 10:00
|
|
*
|
|
* Author: Gerrit van Wingerden [gerritv]
|
|
*
|
|
* Copyright (c) 1996 Microsoft Corporation
|
|
\**************************************************************************/
|
|
|
|
|
|
#include <stddef.h>
|
|
#include <stdarg.h>
|
|
#include <limits.h>
|
|
#include <windef.h>
|
|
#include <winerror.h>
|
|
#include <wingdi.h>
|
|
#include <winddi.h>
|
|
#include <winfont.h>
|
|
#include "fd.h"
|
|
|
|
|
|
|
|
|
|
#if defined(_MIPS_) || defined(_ALPHA_) || defined(_PPC_)
|
|
|
|
|
|
#else // i386
|
|
|
|
VOID vLToE(FLOAT * pe, LONG l)
|
|
{
|
|
PULONG pul = (PULONG)pe;
|
|
|
|
*pul = ulLToE(l);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
VOID
|
|
DbgPrint(
|
|
PCHAR DebugMessage,
|
|
...
|
|
)
|
|
{
|
|
va_list ap;
|
|
va_start(ap, DebugMessage);
|
|
|
|
EngDebugPrint("TestFD", DebugMessage, ap);
|
|
|
|
va_end(ap);
|
|
}
|
|
|
|
|
|
HFF
|
|
TestFdLoadFontFileTE (
|
|
ULONG cFiles,
|
|
ULONG *piFile,
|
|
PVOID *ppvView,
|
|
ULONG *pcjView,
|
|
ULONG ulLangId
|
|
)
|
|
{
|
|
|
|
FONTFILE *pff = NULL;
|
|
ULONG cjIFI;
|
|
|
|
BYTE *pjView0 = (BYTE *)ppvView[0];
|
|
BYTE *pjView1 = (BYTE *)ppvView[1];
|
|
|
|
ULONG cjView0 = pcjView[0];
|
|
ULONG cjView1 = pcjView[1];
|
|
|
|
|
|
ulLangId;
|
|
|
|
if (cFiles != 2)
|
|
return 0;
|
|
|
|
// first file contains facename only
|
|
|
|
cjIFI = ALIGN4(sizeof(IFIMETRICS) + (cjView0 + 1) * sizeof(WCHAR));
|
|
|
|
pff = (FONTFILE*)EngAllocMem(0, sizeof(FONTFILE) + cjIFI, EXFDTAG);
|
|
|
|
if (pff)
|
|
{
|
|
WCHAR *pwszFace;
|
|
ULONG cwc = cjView0; // wcslen(pwszFace);
|
|
IFIMETRICS * pifi;
|
|
|
|
pff->id = 0Xff;
|
|
|
|
// remember these so that we can open files later
|
|
|
|
pff->iFilePFM = piFile[0];
|
|
pff->iFilePFB = piFile[1];
|
|
pff->ulGlyph = *pjView1; // just touch it to be sure it is mapped
|
|
|
|
pifi = pff->pifi = (IFIMETRICS *)(pff+1);
|
|
|
|
memset((PVOID)pifi, 0, cjIFI);
|
|
pifi->cjThis = cjIFI;
|
|
pifi->dpwszFaceName = sizeof(IFIMETRICS);
|
|
pifi->dpwszFamilyName = pifi->dpwszFaceName;
|
|
|
|
// point to terminating zero
|
|
|
|
pifi->dpwszStyleName = pifi->dpwszFaceName
|
|
+sizeof(WCHAR) * cwc;
|
|
pifi->dpwszUniqueName = pifi->dpwszStyleName;
|
|
|
|
pwszFace = (WCHAR *)((BYTE*)pifi + pifi->dpwszFaceName);
|
|
|
|
EngMultiByteToWideChar(
|
|
1252, // CodePage,
|
|
pwszFace, // LPWSTR WideCharString,
|
|
cwc * sizeof(WCHAR) , // BytesInWideCharString,
|
|
(LPSTR)pjView0, // MultiByteString
|
|
(INT)cjView0 // BytesInMultiByteString
|
|
);
|
|
|
|
if (cwc > 2)
|
|
cwc-=2; // hack to get rid of \r\n at the end of the line
|
|
|
|
pwszFace[cwc] = L'\0'; // zero terminate
|
|
|
|
pifi->fwdWinAscender = 4;
|
|
pifi->fwdWinDescender = 3;
|
|
pifi->fwdUnitsPerEm = pifi->fwdWinDescender + pifi->fwdWinAscender;
|
|
|
|
pifi->usWinWeight = 400;
|
|
|
|
pifi->flInfo = ( FM_INFO_TECH_BITMAP
|
|
| FM_INFO_RETURNS_BITMAPS
|
|
| FM_INFO_1BPP
|
|
| FM_INFO_INTEGER_WIDTH
|
|
| FM_INFO_RIGHT_HANDED
|
|
| FM_INFO_NONNEGATIVE_AC
|
|
);
|
|
|
|
pifi->fwdMacAscender = pifi->fwdWinAscender;
|
|
pifi->fwdMacDescender = -pifi->fwdWinDescender;
|
|
pifi->fwdMacLineGap = 0;
|
|
|
|
pifi->fwdTypoAscender = pifi->fwdMacAscender;
|
|
pifi->fwdTypoDescender = pifi->fwdMacDescender;
|
|
pifi->fwdTypoLineGap = pifi->fwdMacLineGap;
|
|
|
|
pifi->fwdMaxCharInc = pifi->fwdAveCharWidth = 5;
|
|
|
|
pifi->fwdUnderscoreSize = 1;
|
|
pifi->fwdUnderscorePosition = -(FWORD)(pifi->fwdUnderscoreSize / 2 + 1);
|
|
pifi->fwdStrikeoutSize = pifi->fwdUnderscoreSize;
|
|
pifi->fwdStrikeoutPosition = pifi->fwdWinAscender / 2;
|
|
|
|
pifi->wcFirstChar = pifi->chFirstChar = THEGLYPH;
|
|
pifi->wcLastChar = pifi->chLastChar = THEGLYPH;
|
|
pifi->wcBreakChar = pifi->chBreakChar = THEGLYPH;
|
|
pifi->wcDefaultChar = pifi->chDefaultChar = THEGLYPH;
|
|
|
|
pifi->fwdCapHeight = pifi->fwdUnitsPerEm/2;
|
|
pifi->fwdXHeight = pifi->fwdUnitsPerEm/4;
|
|
|
|
pifi->dpCharSets = 0; // no multiple charsets in bm fonts
|
|
|
|
// All the fonts that this font driver will see are to be rendered left
|
|
// to right
|
|
|
|
pifi->ptlBaseline.x = 1;
|
|
pifi->ptlBaseline.y = 0;
|
|
|
|
pifi->ptlAspect.y = 1;
|
|
pifi->ptlAspect.x = 1;
|
|
|
|
pifi->rclFontBox.left = 0;
|
|
pifi->rclFontBox.top = (LONG) pifi->fwdTypoAscender;
|
|
pifi->rclFontBox.right = (LONG) pifi->fwdMaxCharInc;
|
|
pifi->rclFontBox.bottom = (LONG) pifi->fwdTypoDescender;
|
|
|
|
// achVendorId, unknown, don't bother figure it out from copyright msg
|
|
|
|
pifi->achVendId[0] = 'U';
|
|
pifi->achVendId[1] = 'n';
|
|
pifi->achVendId[2] = 'k';
|
|
pifi->achVendId[3] = 'n';
|
|
|
|
}
|
|
|
|
return (HFF)pff;
|
|
}
|
|
|
|
|
|
LONG TestFdQueryFontCaps(ULONG culCaps, PULONG pulCaps)
|
|
{
|
|
pulCaps[0] = 2L;
|
|
|
|
pulCaps[1] = QC_1BIT;
|
|
return(2L);
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
TestFdUnloadFontFileTE (
|
|
HFF hff
|
|
)
|
|
{
|
|
if (hff)
|
|
EngFreeMem((PVOID)hff);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
DHPDEV
|
|
TestFdEnablePDEV(
|
|
DEVMODEW* pdm,
|
|
PWSTR pwszLogAddr,
|
|
ULONG cPat,
|
|
HSURF* phsurfPatterns,
|
|
ULONG cjCaps,
|
|
ULONG* pdevcaps,
|
|
ULONG cjDevInfo,
|
|
DEVINFO* pdi,
|
|
HDEV hdev,
|
|
PWSTR pwszDeviceName,
|
|
HANDLE hDriver)
|
|
{
|
|
|
|
PVOID* ppdev;
|
|
pdm;
|
|
pwszLogAddr;
|
|
cPat;
|
|
phsurfPatterns;
|
|
cjCaps;
|
|
pdevcaps;
|
|
cjDevInfo;
|
|
pdi;
|
|
hdev;
|
|
pwszDeviceName;
|
|
hDriver;
|
|
|
|
//
|
|
// Allocate a four byte PDEV for now
|
|
// We can grow it if we ever need to put information in it.
|
|
//
|
|
|
|
ppdev = (PVOID*) EngAllocMem(0, sizeof(PVOID), EXFDTAG);
|
|
|
|
return ((DHPDEV) ppdev);
|
|
}
|
|
|
|
|
|
VOID
|
|
TestFdDisablePDEV(
|
|
DHPDEV dhpdev)
|
|
{
|
|
EngFreeMem(dhpdev);
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
TestFdCompletePDEV(
|
|
DHPDEV dhpdev,
|
|
HDEV hdev)
|
|
{
|
|
dhpdev;
|
|
hdev;
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
PIFIMETRICS
|
|
TestFdQueryFont (
|
|
DHPDEV dhpdev,
|
|
HFF hff,
|
|
ULONG iFace,
|
|
ULONG *pid
|
|
)
|
|
{
|
|
dhpdev;
|
|
pid;
|
|
|
|
//
|
|
// Validate handle.
|
|
//
|
|
if (hff == HFF_INVALID)
|
|
return (PIFIMETRICS) NULL;
|
|
|
|
// Return the pointer to IFIMETRICS.
|
|
|
|
return ((FONTFILE *)hff)->pifi;
|
|
}
|
|
|
|
|
|
|
|
|
|
FD_GLYPHSET *gpgset = NULL;
|
|
|
|
PVOID
|
|
TestFdQueryFontTree (
|
|
DHPDEV dhpdev,
|
|
HFF hff,
|
|
ULONG iFace,
|
|
ULONG iMode,
|
|
ULONG *pid
|
|
)
|
|
{
|
|
dhpdev;
|
|
pid;
|
|
|
|
//
|
|
// Validate parameters.
|
|
//
|
|
if (hff == HFF_INVALID)
|
|
return ((PVOID) NULL);
|
|
|
|
//
|
|
// Which mode?
|
|
//
|
|
switch (iMode)
|
|
{
|
|
case QFT_LIGATURES:
|
|
case QFT_KERNPAIRS:
|
|
|
|
//
|
|
// There are no ligatures or kerning pairs for the bitmap fonts,
|
|
// therefore we return NULL
|
|
//
|
|
return ((PVOID) NULL);
|
|
|
|
case QFT_GLYPHSET:
|
|
|
|
return gpgset;
|
|
|
|
default:
|
|
|
|
//
|
|
// Should never get here.
|
|
//
|
|
return ((PVOID) NULL);
|
|
}
|
|
}
|
|
|
|
|
|
LONG
|
|
TestFdQueryFontFile (
|
|
HFF hff, // handle to font file
|
|
ULONG ulMode, // type of query
|
|
ULONG cjBuf, // size of buffer (in BYTEs)
|
|
PULONG pulBuf // return buffer (NULL if requesting size of data)
|
|
)
|
|
{
|
|
// Verify the HFF.
|
|
|
|
if (hff == HFF_INVALID)
|
|
{
|
|
return(FD_ERROR);
|
|
}
|
|
|
|
switch(ulMode)
|
|
{
|
|
case QFF_DESCRIPTION:
|
|
|
|
// Otherwise, substitute the facename.
|
|
#ifdef IFTIME
|
|
|
|
{
|
|
//
|
|
// There is no description string associated with the font therefore we
|
|
// substitue the facename of the first font in the font file.
|
|
//
|
|
IFIMETRICS *pifi = ((FONTFILE *)hff)->pifi;
|
|
WCHAR * pwszFacename = (WCHAR*)((PBYTE) pifi + pifi->dpwszFaceName);
|
|
ULONG cjFacename = (wcslen(pwszFacename) + 1) * sizeof(WCHAR);
|
|
|
|
//
|
|
// If there is a buffer, copy to it.
|
|
//
|
|
if ( pulBuf != (PULONG) NULL )
|
|
{
|
|
//
|
|
// Is buffer big enough?
|
|
//
|
|
if ( cjBuf < cjFacename )
|
|
{
|
|
return (FD_ERROR);
|
|
}
|
|
else
|
|
{
|
|
RtlCopyMemory((PVOID) pulBuf,
|
|
(PVOID) pwszFacename,
|
|
cjFacename);
|
|
}
|
|
}
|
|
return ((LONG) cjFacename);
|
|
}
|
|
#else
|
|
return 0;
|
|
#endif
|
|
|
|
case QFF_NUMFACES:
|
|
return 1;
|
|
|
|
default:
|
|
return FD_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ULONG cjTestFdDeviceMetrics( FONTFILE *pff, FD_DEVICEMETRICS *pdevm)
|
|
{
|
|
// compute the accelerator flags for this font
|
|
|
|
IFIMETRICS *pifi = pff->pifi;
|
|
|
|
pdevm->flRealizedType =
|
|
(
|
|
FDM_TYPE_BM_SIDE_CONST | // all char bitmaps have the same cy
|
|
FDM_TYPE_MAXEXT_EQUAL_BM_SIDE |
|
|
FDM_TYPE_CHAR_INC_EQUAL_BM_BASE |
|
|
FDM_TYPE_CONST_BEARINGS | // ac spaces for all chars the same, not 0 necessarilly
|
|
FDM_TYPE_ZERO_BEARINGS
|
|
);
|
|
|
|
// the direction unit vectors for all ANSI bitmap fonts are the
|
|
// same. We do not even have to look to the font context:
|
|
|
|
vLToE(&pdevm->pteBase.x, 1L);
|
|
vLToE(&pdevm->pteBase.y, 0L);
|
|
vLToE(&pdevm->pteSide.x, 0L);
|
|
vLToE(&pdevm->pteSide.y, -1L); // y axis points down
|
|
|
|
// Set the constant increment for a fixed pitch font. Don't forget to
|
|
// take into account a bold simulation!
|
|
|
|
pdevm->lD = 0;
|
|
|
|
// for a bitmap font there is no difference between notional and device
|
|
// coords, so that the Ascender and Descender can be copied directly
|
|
// from PIFIMETRICS where these two numbers are in notional coords
|
|
|
|
pdevm->fxMaxAscender = LTOFX((LONG)pifi->fwdWinAscender);
|
|
pdevm->fxMaxDescender = LTOFX((LONG)pifi->fwdWinDescender);
|
|
|
|
pdevm->ptlUnderline1.x = 0L;
|
|
pdevm->ptlUnderline1.y = - pifi->fwdUnderscorePosition;
|
|
|
|
pdevm->ptlStrikeOut.y = - pifi->fwdStrikeoutPosition;
|
|
pdevm->ptlStrikeOut.x = (LONG)pifi->fwdStrikeoutPosition / 2 ;
|
|
|
|
pdevm->ptlULThickness.x = 0;
|
|
pdevm->ptlULThickness.y = (LONG)pifi->fwdUnderscoreSize;
|
|
|
|
pdevm->ptlSOThickness.x = 0;
|
|
pdevm->ptlSOThickness.y = (LONG)pifi->fwdStrikeoutSize;
|
|
|
|
// for a bitmap font there is no difference between notional and device
|
|
// coords, so that the Ascender and Descender can be copied directly
|
|
// from PIFIMETRICS where these two numbers are in notional coords
|
|
|
|
pdevm->ptlUnderline1.x = 0L;
|
|
pdevm->ptlUnderline1.y = - pifi->fwdUnderscorePosition;
|
|
|
|
pdevm->ptlStrikeOut.y = - pifi->fwdStrikeoutPosition;
|
|
pdevm->ptlStrikeOut.x = (LONG)pifi->fwdStrikeoutPosition / 2;
|
|
|
|
pdevm->ptlULThickness.x = 0;
|
|
pdevm->ptlULThickness.y = (LONG)pifi->fwdUnderscoreSize;
|
|
|
|
pdevm->ptlSOThickness.x = 0;
|
|
pdevm->ptlSOThickness.y = (LONG)pifi->fwdStrikeoutSize;
|
|
|
|
pdevm->cxMax = pifi->fwdMaxCharInc;
|
|
pdevm->cyMax = pifi->fwdUnitsPerEm;
|
|
pdevm->cjGlyphMax = CJ_BMP(pdevm->cxMax,pdevm->cyMax);
|
|
|
|
return (sizeof(FD_DEVICEMETRICS));
|
|
}
|
|
|
|
|
|
|
|
LONG
|
|
TestFdQueryFontData (
|
|
DHPDEV dhpdev,
|
|
FONTOBJ *pfo,
|
|
ULONG iMode,
|
|
HGLYPH hg,
|
|
GLYPHDATA *pgd,
|
|
PVOID pv,
|
|
ULONG cjSize
|
|
)
|
|
{
|
|
|
|
FONTFILE * pff = (FONTFILE *)(pfo->iFile);
|
|
IFIMETRICS *pifi = pff->pifi;
|
|
BYTE *pjViewPFB;
|
|
ULONG cjViewPFB;
|
|
|
|
LONG cjGlyphData = 0;
|
|
|
|
int i;
|
|
GLYPHBITS *pgb;
|
|
BYTE *pjV;
|
|
|
|
ULONG cx = (ULONG)pifi->fwdMaxCharInc;
|
|
ULONG j, cjScan = CJ_SCAN(cx);
|
|
|
|
dhpdev;
|
|
|
|
if (pfo->pvProducer == (PVOID) NULL)
|
|
pfo->pvProducer = pff;
|
|
|
|
if (!EngMapFontFile(pff->iFilePFB, (PULONG *)&pjViewPFB, &cjViewPFB))
|
|
return FD_ERROR;
|
|
|
|
if (pff->ulGlyph != (ULONG)(*pjViewPFB))
|
|
{
|
|
DbgPrint("Bogus PFB FILE\n");
|
|
}
|
|
|
|
EngUnmapFontFile(pff->iFilePFB);
|
|
|
|
// What mode?
|
|
|
|
switch (iMode)
|
|
{
|
|
|
|
case QFD_GLYPHANDBITMAP:
|
|
|
|
// Fill in the GLYPHDATA portion (metrics) of the RASTERGLYPH.
|
|
|
|
cjGlyphData = CJ_BMP(cx, pifi->fwdUnitsPerEm);
|
|
|
|
if (pgd)
|
|
{
|
|
pgd->gdf.pgb = NULL;
|
|
pgd->hg = THEGLYPH;
|
|
pgd->fxD = pifi->fwdMaxCharInc << 4;
|
|
pgd->fxA = 0; // Prebearing amount: A*r.
|
|
pgd->fxAB = pgd->fxD;
|
|
pgd->fxInkTop = (pifi->fwdWinAscender << 4);
|
|
pgd->fxInkBottom = -pifi->fwdWinDescender << 4;
|
|
pgd->rclInk = pifi->rclFontBox;
|
|
pgd->ptqD.x.HighPart = (LONG)pgd->fxD;
|
|
pgd->ptqD.x.LowPart = 0;
|
|
pgd->ptqD.y.HighPart = 0;
|
|
pgd->ptqD.y.LowPart = 0;
|
|
}
|
|
|
|
// Fill in the bitmap portion of the RASTERGLYPH.
|
|
|
|
if (pv)
|
|
{
|
|
// Record the pointer to the RASTERGLYPH in the pointer table.
|
|
|
|
pgb = (GLYPHBITS *)pv;
|
|
pjV = pgb->aj;
|
|
|
|
pgb->sizlBitmap.cx = cx;
|
|
pgb->sizlBitmap.cy = pifi->fwdUnitsPerEm;
|
|
|
|
pgb->ptlOrigin.x = 0;
|
|
pgb->ptlOrigin.y = - pifi->fwdWinAscender;
|
|
|
|
|
|
for (i = 0; i < pifi->fwdUnitsPerEm; i++, pjV += cjScan)
|
|
{
|
|
for (j = 0; j < cjScan; j++)
|
|
pjV[j] = (BYTE)pff->ulGlyph;
|
|
|
|
}
|
|
|
|
if (pgd != NULL )
|
|
{
|
|
pgd->gdf.pgb = pgb;
|
|
}
|
|
}
|
|
|
|
return cjGlyphData;
|
|
|
|
case QFD_MAXEXTENTS:
|
|
// If buffer NULL, return size.
|
|
|
|
if ( pv == (PVOID) NULL )
|
|
return (sizeof(FD_DEVICEMETRICS));
|
|
|
|
// Otherwise, copy the data structure.
|
|
|
|
else
|
|
return cjTestFdDeviceMetrics(pff, (FD_DEVICEMETRICS *) pv);
|
|
|
|
case QFD_GLYPHANDOUTLINE:
|
|
default:
|
|
|
|
return FD_ERROR;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// The driver function table with all function index/address pairs
|
|
|
|
DRVFN gadrvfnTestFd[] =
|
|
{
|
|
{ INDEX_DrvEnablePDEV, (PFN) TestFdEnablePDEV, },
|
|
{ INDEX_DrvDisablePDEV, (PFN) TestFdDisablePDEV, },
|
|
{ INDEX_DrvCompletePDEV, (PFN) TestFdCompletePDEV, },
|
|
{ INDEX_DrvLoadFontFile, (PFN) TestFdLoadFontFileTE, },
|
|
{ INDEX_DrvUnloadFontFile, (PFN) TestFdUnloadFontFileTE, },
|
|
{ INDEX_DrvQueryFontCaps, (PFN) TestFdQueryFontCaps, },
|
|
{ INDEX_DrvQueryFont, (PFN) TestFdQueryFont, },
|
|
{ INDEX_DrvQueryFontFile, (PFN) TestFdQueryFontFile, },
|
|
{ INDEX_DrvQueryFontTree, (PFN) TestFdQueryFontTree, },
|
|
{ INDEX_DrvQueryFontData, (PFN) TestFdQueryFontData, },
|
|
};
|
|
|
|
|
|
BOOL DrvEnableDriver(
|
|
ULONG iEngineVersion,
|
|
ULONG cj,
|
|
PDRVENABLEDATA pded)
|
|
{
|
|
iEngineVersion;
|
|
cj;
|
|
|
|
DbgPrint("DrvEnableDriver called\n");
|
|
|
|
pded->pdrvfn = gadrvfnTestFd;
|
|
pded->c = sizeof(gadrvfnTestFd) / sizeof(DRVFN);
|
|
pded->iDriverVersion = DDI_DRIVER_VERSION;
|
|
|
|
|
|
gpgset = (FD_GLYPHSET *)EngAllocMem(0, SZ_GLYPHSET(1, 1), EXFDTAG);
|
|
|
|
gpgset->cjThis = SZ_GLYPHSET(1, 1);
|
|
gpgset->flAccel = 0;
|
|
gpgset->cGlyphsSupported = 1;
|
|
gpgset->cRuns = 1;
|
|
gpgset->awcrun[0].wcLow = THEGLYPH;
|
|
gpgset->awcrun[0].cGlyphs = 1;
|
|
gpgset->awcrun[0].phg = (HGLYPH *)&gpgset->awcrun[1];
|
|
*(gpgset->awcrun[0].phg) = THEGLYPH;
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
VOID
|
|
DrvDisableDriver(
|
|
VOID
|
|
)
|
|
{
|
|
EngFreeMem(gpgset);
|
|
}
|