Discussion:
ZwMapViewOfSection again...
(too old to reply)
rep_movsd
2005-03-29 21:41:36 UTC
Permalink
Hi

I am writing a WDM capture driver, which simulates a webcam.
It has to render frames given it by a user mode app which is reading
from a file.
I assumed the best way to pass the frames would be through shared
memory, However, I just cant get it to work...
Heres the relevant code (much of it copied from the testcap sample)

#define SEC_COMMIT 0x08000000
NTSYSAPI NTSTATUS
ZwCreateSection(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
OPTIONAL,
IN PLARGE_INTEGER MaximumSize
OPTIONAL,
IN ULONG SectionPageProtection,
IN ULONG AllocationAttributes,
IN HANDLE FileHandle OPTIONAL
);


WCHAR const SectionNameConst[] = L"\\BaseNamedObjects\\VCamBuffah";
UNICODE_STRING SectionName;
LARGE_INTEGER SecSize;
ULONG ViewSize = 262144;
struct _OBJECT_ATTRIBUTES oa;


BOOLEAN STREAMAPI HwInitialize (IN OUT PHW_STREAM_REQUEST_BLOCK pSrb)
{
STREAM_PHYSICAL_ADDRESS adr;
ULONG Size;
PUCHAR pDmaBuf;
int j;
PPORT_CONFIGURATION_INFORMATION ConfigInfo =
pSrb->CommandData.ConfigInfo;
PHW_DEVICE_EXTENSION pHwDevExt =
(PHW_DEVICE_EXTENSION)ConfigInfo->HwDeviceExtension;

SecSize.QuadPart = ViewSize;
SectionName.Buffer = (PWSTR)&SectionNameConst;
SectionName.Length = wcslen(SectionNameConst) * sizeof(WCHAR);
SectionName.MaximumLength = SectionName.Length + sizeof(WCHAR);

InitializeObjectAttributes(&oa, &SectionName, OBJ_CASE_INSENSITIVE
, NULL, NULL);
pHwDevExt->status = ZwCreateSection( &pHwDevExt->hMap,
SECTION_ALL_ACCESS, &oa, &SecSize, PAGE_READWRITE, SEC_COMMIT, 0);

//ViewSize = 0;
pHwDevExt->pBuf = 0;
if(pHwDevExt->hMap != 0)
{
pHwDevExt->status = ZwMapViewOfSection( pHwDevExt->hMap,
(HANDLE)-1 ,&pHwDevExt->pBuf, 0L, 262144, NULL, &ViewSize, 1, 0,
PAGE_READONLY );
}

AdapterSetInstance (pSrb);

pSrb->Status = STATUS_SUCCESS;
return TRUE;
}

It always reports that the 9th parameter is invalid.

At my wits end, I tried another experiment, I wrote an app to map
memory and stepped through the call for MapViewOfFile, when it
eventually calls ZwMapViewOfSection, the stack has 1, 0 and 2 as the
last 3 parameters to it.

This is weird, because in my app i specify PAGE_READWRITE which is 4,
but it goes to the kernel api as 2!!

Can anyone test this out and give me a solution?
Im so desperate, i am thinking I might have to use a regular file or
named pipe to share data.
Maxim S. Shatskih
2005-03-30 07:55:23 UTC
Permalink
Post by rep_movsd
I am writing a WDM capture driver, which simulates a webcam.
Write it in user mode, it is simpler, unless your goal later is to switch to a
real hardware webcam.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
***@storagecraft.com
http://www.storagecraft.com
rep_movsd
2005-03-30 10:04:51 UTC
Permalink
Post by Maxim S. Shatskih
Post by rep_movsd
I am writing a WDM capture driver, which simulates a webcam.
Write it in user mode, it is simpler, unless your goal later is to switch to a
real hardware webcam.
Hi

I already have a Directshow filter which does the job, but Directshow
source filters do not get enumerated as capture devices by
applications.

Is there a way to tell or trick Directshow to enumerate my filter as a
Capture device, such that it is seen by Yahoo messenger etc as a
webcam.
Alternately, would it be ok to use an input pin in my filter to which
the user mode app writes the data, which will then save the data to a
common buffer that can be used by another instance of the capture
driver filter?
Maxim S. Shatskih
2005-03-30 11:08:42 UTC
Permalink
Post by rep_movsd
I already have a Directshow filter which does the job, but Directshow
source filters do not get enumerated as capture devices by
applications.
??? Ancient-style Video For Windows driver wrapped around by DirectShow's
QCAP.DLL is well-used in applications like MSN Messenger.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
***@storagecraft.com
http://www.storagecraft.com
rep_movsd
2005-03-30 14:42:27 UTC
Permalink
Hi

I dont want to go the VFW driver route yet...

You mentioned something about writing it in user mode.
Is it possible to do what I require in user mode code itself?
If so can you give me a general idea how?
Can a push source filter be registered as a capture device?

Thanks in advance.
Maxim S. Shatskih
2005-03-30 15:34:39 UTC
Permalink
Post by rep_movsd
I dont want to go the VFW driver route yet...
You mentioned something about writing it in user mode.
Is it possible to do what I require in user mode code itself?
Yes. VfW is the simplest way, but you will need Win95 DDK for them.
Post by rep_movsd
Can a push source filter be registered as a capture device?
Surely. QCAP wrapped around the VfW driver is registered this way, and MSN
Messenger or Macromedia Flash Communication Server can use it fine.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
***@storagecraft.com
http://www.storagecraft.com
rep_movsd
2005-03-30 20:23:54 UTC
Permalink
Post by Maxim S. Shatskih
Post by rep_movsd
I dont want to go the VFW driver route yet...
You mentioned something about writing it in user mode.
Is it possible to do what I require in user mode code itself?
Yes. VfW is the simplest way, but you will need Win95 DDK for them.
Post by rep_movsd
Can a push source filter be registered as a capture device?
Surely. QCAP wrapped around the VfW driver is registered this way, and MSN
Messenger or Macromedia Flash Communication Server can use it fine.
Hi
Thanks, I think I have the solution...
It was quite simple, All I had to do is register my source filter using
the
AM_KSCATEGORY_CAPTURE category with the right moniker.

This allowed the filter to appear as a capture device, but Yahoo
Messenger gave an error ( Your webcam could not be started ), I guess
its because I havent implemented the IAMxxx and other interfaces. Now
that its in usermode all is well and were back in Kansas and I can fix
it.

However, this turned out to have an unpleasant side effect... It
deregistered my TV tuner capture filter!!

Why did this happen? Do i have to go to the end of the enumeration
before using the moniker IFiltermapper2->RegisterFilter ?
w***@163.com
2005-04-01 01:13:06 UTC
Permalink
why don't you create the shared memory in kernel space then tell the
application about the virtual address of such a kernel shared memory?

NTSTATUS
XXX_CreateSharedMemory (
IN ULONG ulSize,
OUT PSHARE_MEM_DESC pDesc
)
{
LPVOID lpBuf;
PMDL pMdl;
ULONG ulActSize;

if (NULL == pDesc) {
return STATUS_INVALID_PARAMETER;
}

ulActSize = (ulSize + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1));

lpBuf = ExAllocatePoolWithTag (
NonPagedPool,
ulActSize,
'MXXX'
);

if (NULL == lpBuf) {
return STATUS_NO_MEMORY;
}

pMdl = IoAllocateMdl (
lpBuf,
ulActSize,
FALSE,
FALSE,
NULL
);

if (NULL == pMdl) {
ExFreePool (lpBuf);
return STATUS_NO_MEMORY;
}

MmBuildMdlForNonPagedPool (pMdl);

pDesc->m_ulUserVirtAddr = (ULONG)MmMapLockedPages (
pMdl,
UserMode
);

if (0 == pDesc->m_ulUserVirtAddr) {
IoFreeMdl (pMdl);
ExFreePool (lpBuf);
return STATUS_NO_MEMORY;
}

pDesc->m_pSharedBuffer = lpBuf;
pDesc->m_pMdlUserBuffer = pMdl;
pDesc->m_ulActSize = ulActSize;

return STATUS_SUCCESS;
}
Maxim S. Shatskih
2005-04-01 06:34:52 UTC
Permalink
Beware of security issues here. The mapping works only in terms of pages,
and you will expose the whole page of the kernel memory to user. So, at least
the allocation size must be page-aligned.
Beware of sync issues here about serializing the user and kernel accesses
to this memory.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
***@storagecraft.com
http://www.storagecraft.com
Post by w***@163.com
why don't you create the shared memory in kernel space then tell the
application about the virtual address of such a kernel shared memory?
NTSTATUS
XXX_CreateSharedMemory (
IN ULONG ulSize,
OUT PSHARE_MEM_DESC pDesc
)
{
LPVOID lpBuf;
PMDL pMdl;
ULONG ulActSize;
if (NULL == pDesc) {
return STATUS_INVALID_PARAMETER;
}
ulActSize = (ulSize + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1));
lpBuf = ExAllocatePoolWithTag (
NonPagedPool,
ulActSize,
'MXXX'
);
if (NULL == lpBuf) {
return STATUS_NO_MEMORY;
}
pMdl = IoAllocateMdl (
lpBuf,
ulActSize,
FALSE,
FALSE,
NULL
);
if (NULL == pMdl) {
ExFreePool (lpBuf);
return STATUS_NO_MEMORY;
}
MmBuildMdlForNonPagedPool (pMdl);
pDesc->m_ulUserVirtAddr = (ULONG)MmMapLockedPages (
pMdl,
UserMode
);
if (0 == pDesc->m_ulUserVirtAddr) {
IoFreeMdl (pMdl);
ExFreePool (lpBuf);
return STATUS_NO_MEMORY;
}
pDesc->m_pSharedBuffer = lpBuf;
pDesc->m_pMdlUserBuffer = pMdl;
pDesc->m_ulActSize = ulActSize;
return STATUS_SUCCESS;
}
Loading...