Mirror Driver - something wrong with pso->pvBits

I have compiled perm2 and I tried to install it through Control panel->Add hardware (It’s the same way I have been installing Mirror Display Driver) but when trying to add the perm2.inf I see nothing in install list.
How can I use or test this driver?

Could someone answer to my question, please.
As I have understood that if I will do through IOCTL_VIDEO_MAP_VIDEO_MEMORY.
I must to do in MirrorStartIO handling with IOCTL_VIDEO_MAP_VIDEO_MEMORY and then do
EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_MAP_VIDEO_MEMORY, &VideoMemory, // input buffer sizeof(VIDEO_MEMORY), &VideoMemoryInfo, // output buffer sizeof(VideoMemoryInfo), &dLength)
in DrvEnablePDEV
to get the buffer pointer pso->pvBits through ?
Or i’m saying wrong?

xxxxx@gmail.com wrote:

Could someone answer to my question, please.
As I have understood that if I will do through IOCTL_VIDEO_MAP_VIDEO_MEMORY.
I must to do in MirrorStartIO handling with IOCTL_VIDEO_MAP_VIDEO_MEMORY and then do
EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_MAP_VIDEO_MEMORY, &VideoMemory, // input buffer sizeof(VIDEO_MEMORY), &VideoMemoryInfo, // output buffer sizeof(VideoMemoryInfo), &dLength)
in DrvEnablePDEV
to get the buffer pointer pso->pvBits through ?
Or i’m saying wrong?

I’m not actually sure what you’re saying, but I don’t think this will do
what you want. That ioctl is used when you have a hardware frame buffer
and you need to make it available in virtual memory.

Have you read the documentation? pso->pvBits is only populated if the
surface is GDI-managed and matches a standard bitmap format. The stock
mirror driver sample uses EngCreateDeviceSurface to create the surface,
which creates a surface that is NOT a standard bitmap format. If you
want a standard format bitmap, you probably want to change
EngCreateDeviceSurface to EngCreateBitmap


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Yes I want to change EngCreateBitmap or to do something like that to get populated pso->pvBits and to get screenshot bits to user-mode app.
But how can I do this?
I read that EngCreateDeviceSurface is returns HSURF and EngCreateBitmap HBITMAP so I don’t know how to change because the types are different.

Ok I think I have found the correct way, but I can’t find where the structure DrvData is situated.(what file do I need to include?)

xxxxx@gmail.com wrote:

Ok I think I have found the correct way, but I can’t find where the structure DrvData is situated.(what file do I need to include?)

I don’t know what you are talking about. Where do you see this?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I have found small piece of code which using EngCreateBitmap in DrvEnableSurface.
And there is unknown structure me DrvData.

xxxxx@gmail.com wrote:

I have found small piece of code which using EngCreateBitmap in DrvEnableSurface.
And there is unknown structure me DrvData.

It’s a bit dangerous to cut and paste unknown code into a driver without
understanding what it does. There is no system-defined structure called
“DrvData”, so I’d have to conclude that it was the driver context
structure for whatever driver you are looking at.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

> Could someone answer to my question, please.

As I have understood that if I will do through
IOCTL_VIDEO_MAP_VIDEO_MEMORY.
I must to do in MirrorStartIO handling with IOCTL_VIDEO_MAP_VIDEO_MEMORY
and then do
EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_MAP_VIDEO_MEMORY,
&VideoMemory, // input buffer sizeof(VIDEO_MEMORY), &VideoMemoryInfo, //
output buffer sizeof(VideoMemoryInfo), &dLength)
in DrvEnablePDEV
to get the buffer pointer pso->pvBits through ?
Or i’m saying wrong?

your are right. you can do in this way! and you should use EngCreateBitmap
instead of EngCreateDeviceSurface.
danny

danny zhao wrote:

Could someone answer to my question, please.
As I have understood that if I will do through
IOCTL_VIDEO_MAP_VIDEO_MEMORY.
I must to do in MirrorStartIO handling with
IOCTL_VIDEO_MAP_VIDEO_MEMORY and then do
EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_MAP_VIDEO_MEMORY,
&VideoMemory, // input buffer sizeof(VIDEO_MEMORY),
&VideoMemoryInfo, // output buffer sizeof(VideoMemoryInfo), &dLength)
in DrvEnablePDEV
to get the buffer pointer pso->pvBits through ?
Or i’m saying wrong?

your are right. you can do in this way! and you should use
EngCreateBitmap instead of EngCreateDeviceSurface.

Danny, why do you think this is right? What memory do you think he will
be mapping with IOCTL_VIDEO_MAP_VIDEO_MEMORY?


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Could someone tell me, please.
What I dis wrong in the code?
I tried to change from EngCreateDeviceSurface to EngCreateBitmap in DrvEnableSurface.
And i did this code
HSURF DrvEnableSurface(
DHPDEV dhpdev)
{
PPDEV ppdev;
HSURF hsurf;
SIZEL sizl;
ULONG ulBitmapType;
FLONG flHooks;
ULONG mirrorsize;
MIRRSURF *mirrsurf;
DHSURF dhsurf;

// Create engine bitmap around frame buffer.

DISPDBG((0,“DrvEnableSurface:\n”));

ppdev = (PPDEV) dhpdev;

ppdev->ptlOrg.x = 0;
ppdev->ptlOrg.y = 0;

sizl.cx = ppdev->cxScreen;
sizl.cy = ppdev->cyScreen;

if (ppdev->ulBitCount == 16)
{
ulBitmapType = BMF_16BPP;
flHooks = HOOKS_BMF16BPP;
}
else if (ppdev->ulBitCount == 24)
{
ulBitmapType = BMF_24BPP;
flHooks = HOOKS_BMF24BPP;
}
else
{
ulBitmapType = BMF_32BPP;
flHooks = HOOKS_BMF32BPP;
}

flHooks |= flGlobalHooks;

mirrorsize = (ULONG)(sizeof(MIRRSURF) +
ppdev->lDeltaScreen * sizl.cy);

mirrsurf = (MIRRSURF *) EngAllocMem(FL_ZERO_MEMORY,
mirrorsize,
0x4D495252);
if (!mirrsurf) {
RIP(“DISP DrvEnableSurface failed EngAllocMem\n”);
return(FALSE);
}

/*
dhsurf = (DHSURF) mirrsurf;

hsurf = EngCreateDeviceSurface(dhsurf,
sizl,
ulBitmapType);*/

dhsurf = (DHSURF) mirrsurf;
(HBITMAP)hsurf = EngCreateBitmap(sizl, ppdev->lDeltaScreen, ulBitmapType, 0, dhsurf);

if (hsurf == (HSURF) 0)
{
RIP(“DISP DrvEnableSurface failed EngCreateBitmap\n”);
return(FALSE);
}

if (!EngAssociateSurface(hsurf, ppdev->hdevEng, flHooks))
{
RIP(“DISP DrvEnableSurface failed EngAssociateSurface\n”);
EngDeleteSurface(hsurf);
return(FALSE);
}

ppdev->hsurfEng = (HSURF) hsurf;
ppdev->pvTmpBuffer = (PVOID) dhsurf;

mirrsurf->cx = ppdev->cxScreen;
mirrsurf->cy = ppdev->cyScreen;
mirrsurf->lDelta = ppdev->lDeltaScreen;
mirrsurf->ulBitCount = ppdev->ulBitCount;
mirrsurf->bIsScreen = TRUE;

return(hsurf);
}
And I got the blue screen and the crush-dump is
!analyze -f -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Unknown bugcheck code (10000050)
Unknown bugcheck description
Arguments:
Arg1: e1f2fef8
Arg2: 00000000
Arg3: bf95f1b9
Arg4: 00000002

Debugging Details:

Could not read faulting driver name

READ_ADDRESS: e1f2fef8

FAULTING_IP:
win32k!vLoadAndConvert32BitfieldsToBGRA+1e
bf95f1b9 ff36 push dword ptr [esi]

MM_INTERNAL_CODE: 2

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0x50

LAST_CONTROL_TRANSFER: from bf9030fb to bf95f1b9

STACK_TEXT:
f8060720 bf9030fb e1710748 e1f2fef8 00000000 win32k!vLoadAndConvert32BitfieldsToBGRA+0x1e
f806075c bf90377a e1f2fef8 e1710748 fffff000 win32k!AlphaScanLineBlend+0x14a
f8060990 bf8b5005 e1a07598 e148abb8 f80609cc win32k!EngAlphaBlend+0x313
f8060a44 bf8b29b8 00000000 e1b2b9d8 00000000 win32k!PDEVOBJ::vProfileDriver+0x18e
f8060a70 bf8b3272 e1b2b9d8 e1473c28 e1b7aa58 win32k!hCreateHDEV+0x548
f8060be8 bf8b9b84 f8060cb0 e14c6940 00000001 win32k!DrvCreateMDEV+0x4dc
f8060cdc bf8bbe20 f8060cb0 e15f0008 00000000 win32k!DrvChangeDisplaySettings+0x251
f8060d20 bf8bbd13 0012ff60 00147348 00000000 win32k!xxxUserChangeDisplaySettings+0x141
f8060d48 8053c808 0012ff60 00147348 00000000 win32k!NtUserChangeDisplaySettings+0x4a
f8060d64 7c90eb94 badb0d00 0012ff3c 00000000 nt!ObpPushStackInfo+0x75
WARNING: Frame IP not in any known module. Following frames may be wrong.
0012ff68 00000000 00000000 00000000 00000000 0x7c90eb94

FOLLOWUP_IP:
win32k!vLoadAndConvert32BitfieldsToBGRA+1e
bf95f1b9 ff36 push dword ptr [esi]

FOLLOWUP_NAME: MachineOwner

SYMBOL_NAME: win32k!vLoadAndConvert32BitfieldsToBGRA+1e

MODULE_NAME: win32k

IMAGE_NAME: win32k.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 41107f7a

STACK_COMMAND: kb

BUCKET_ID: 0x50_win32k!vLoadAndConvert32BitfieldsToBGRA+1e

Followup: MachineOwner

Can someone say, how can I change to EngCreateBitmap correctly?

xxxxx@gmail.com wrote:

Could someone tell me, please.
What I dis wrong in the code?
I tried to change from EngCreateDeviceSurface to EngCreateBitmap in DrvEnableSurface.
And i did this code

mirrorsize = (ULONG)(sizeof(MIRRSURF) +
ppdev->lDeltaScreen * sizl.cy);

mirrsurf = (MIRRSURF *) EngAllocMem(FL_ZERO_MEMORY,
mirrorsize,
0x4D495252);
if (!mirrsurf) {
RIP(“DISP DrvEnableSurface failed EngAllocMem\n”);
return(FALSE);
}

dhsurf = (DHSURF) mirrsurf;
(HBITMAP)hsurf = EngCreateBitmap(sizl, ppdev->lDeltaScreen, ulBitmapType, 0, dhsurf);

mirrsurf->cx = ppdev->cxScreen;
mirrsurf->cy = ppdev->cyScreen;
mirrsurf->lDelta = ppdev->lDeltaScreen;
mirrsurf->ulBitCount = ppdev->ulBitCount;
mirrsurf->bIsScreen = TRUE;

And I got the blue screen and the crush-dump is

Do you count on using the information in MIRRSURF later? You don’t pass
a DHSURF to EngCreateBitmap. You just pass a raw buffer to hold the
bits (as the documentation clearly says). Your MIRRSURF structure is
going to be overwritten by the first pixels in the frame buffer.

In your case, you can probably just let GDI allocate the bits, and pass
NULL for the 5th parameter.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

xxxxx@gmail.com wrote:

Can someone say, how can I change to EngCreateBitmap correctly?

Dude, you have to wait more than a couple of hours to get a response.
This is not an on-demand consulting service. This is a mailing list
where certain experts give of their knowledge freely, but only if they
have the spare time.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Ok. Sorry.
Tim thank you for your answer.

If you need the video stream for remote control you can use wmsdk with on the fly encoding with predifined quality(with no drivers at all). Find out the keywords… IWMEncProfile2, IWMEncVideoSource2.

xxxxx@mail.ru wrote:

If you need the video stream for remote control you can use wmsdk with on the fly encoding with predifined quality(with no drivers at all).

I think you addressing an entirely different problem. He’s trying to
remote the desktop surface, not a video.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

>

Danny, why do you think this is right? What memory do you think he will
be mapping with IOCTL_VIDEO_MAP_VIDEO_MEMORY?

hi,tim
the mirror drivers in ddk include a dispaly driver and a miniport
driver. IOCTL_VIDEO_MAP_VIDEO_MEMORY is the standard ioctrl for real
display driver to get the video buffer from real miniport driver. although
the mirror drivers are not real drivers ,but we can simulate this method of
the real display driver . so we can allocate memory in mirror miniport
driver.
i disassemble vnc driver and found it implemented in similar way(not 100%
astandard IOCTL_VIDEO_MAP_VIDEO_MEMORY ,in facet allocate memory in
minidriver and return the pointer to the display driver), and i already
implemented in my driver and it works well.
it is only one method, you can allocate memory directly in display driver.
it is the benefit to according with the standard method of real dispaly
driver
danny

>

mirrorsize = (ULONG)(sizeof(MIRRSURF) +
ppdev->lDeltaScreen * sizl.cy);

mirrsurf = (MIRRSURF *) EngAllocMem(FL_ZERO_MEMORY,
mirrorsize,
0x4D495252);

ppdev->lDeltaScreen is set to 0 in bInitPDEV. do you understand the use of
mirrorsize memory in mirror dispaly driver? it is not the simulated video
buffer that perhaps you thought. if you want to allocate memory as the
simulted video buffer,you can do as i have told through miniport driver.
or you can directly allocate mirrosize = sizl.cy*
sizl.cx*(ppdev->ulBitCount/8).
danny

Ok now method through ppdev->ulBitCount is working properly. Tim, thank you very much for help :slight_smile:
And I got another problem when I’m doing the screenshot through ppdev->ulBitCount and when I load him in my app(I’m using standard method) I get not RGBA format, but RBGA format. (I understand that RGBA is stored as BGRA format, contrary)
Strange, but Red channel is in the place and only Green and Blue channels are swaped.
Could someone answer to my question, please.