windows-nt/Source/XPSP1/NT/drivers/wdm/capture/mini/1394dcam/capprop.c
2020-09-26 16:20:57 +08:00

1559 lines
57 KiB
C

//===========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1996 - 2000 Microsoft Corporation. All Rights Reserved.
//
//===========================================================================
/*++
Module Name:
CapProp.c
Abstract:
Stream class based WDM driver for 1934 Desktop Camera.
This file contains code to handle the video and camera control properties.
Author:
Yee J. Wu 9-Sep-97
Environment:
Kernel mode only
Revision History:
Yee J. Wu 16-Nov-00
Make getting, advertising, and setting device properties more generic
by querying feature from the device directly instead of static settings
based on the vendor. The default and initial current settings will be
read from registry (from the INF). The current setting will continue
to be updated and used thereafter. For device that does not have its INF
section, mid-range will be used as its default and initial settings.
--*/
#include "strmini.h"
#include "ksmedia.h"
#include "1394.h"
#include "wdm.h" // for DbgBreakPoint() defined in dbg.h
#include "dbg.h"
#include "dcamdef.h"
#include "dcampkt.h"
#include "capprop.h" // Video and camera property function prototype
#include "PropData.h" // Generic device properties that are readonly
//
// Registry subky and values wide character strings.
//
WCHAR wszSettings[] = L"Settings";
WCHAR wszVModeInq0[] = L"VModeInq0";
WCHAR wszBrightness[] = L"Brightness";
WCHAR wszHue[] = L"Hue";
WCHAR wszSaturation[] = L"Saturation";
WCHAR wszSharpness[] = L"Sharpness";
WCHAR wszWhiteBalance[] = L"WhiteBalance";
WCHAR wszZoom[] = L"Zoom";
WCHAR wszFocus[] = L"Focus";
WCHAR wszBrightnessDef[] = L"BrightnessDef";
WCHAR wszHueDef[] = L"HueDef";
WCHAR wszSaturationDef[] = L"SaturationDef";
WCHAR wszSharpnessDef[] = L"SharpnessDef";
WCHAR wszWhiteBalanceDef[] = L"WhiteBalanceDef";
WCHAR wszZoomDef[] = L"ZoomDef";
WCHAR wszFocusDef[] = L"FocusDef";
NTSTATUS
DCamGetProperty(
IN PIRB pIrb,
PDCAM_EXTENSION pDevExt,
ULONG ulFieldOffset,
LONG * plValue,
ULONG * pulCapability,
ULONG * pulFlags,
DCamRegArea * pFeature
)
/*
Get a device property from its register. Return the capabilites and current settings.
*/
{
NTSTATUS status, StatusWait;
// Make sure that device support this feature.
if(pFeature->Feature.PresenceInq == 0) {
DbgMsg1(("\'OffSet:%d not supported!\n", ulFieldOffset));
return STATUS_NOT_SUPPORTED;
}
// Serialize read/write to the device register
StatusWait = KeWaitForSingleObject( &pDevExt->hMutexProperty, Executive, KernelMode, FALSE, 0 );
*pulCapability = 0;
if (pFeature->Feature.AutoMode)
*pulCapability |= KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO; // or == KSPROPERTY_CAMERACONTROL_FLAGS_AUTO
if (pFeature->Feature.ManualMode)
*pulCapability |= KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
pDevExt->RegArea.AsULONG = 0;
status = DCamReadRegister(pIrb, pDevExt, ulFieldOffset, &(pDevExt->RegArea.AsULONG));
if(NT_SUCCESS(status)) {
pDevExt->RegArea.AsULONG = bswap(pDevExt->RegArea.AsULONG);
DbgMsg1(("\'GetProperty: CurrentSettings: Offset:%d; %x; Pres:%d;OnePush:%d;OnOff:%d;Auto:%d;Value:%d\n",
ulFieldOffset,
pDevExt->RegArea.AsULONG,
pDevExt->RegArea.Brightness.PresenceInq,
pDevExt->RegArea.Brightness.OnePush,
pDevExt->RegArea.Brightness.OnOff,
pDevExt->RegArea.Brightness.AutoMode,
pDevExt->RegArea.Brightness.Value
));
*plValue = (LONG) pDevExt->RegArea.Brightness.Value;
// These only valid if it has these capabilities.
if (pDevExt->RegArea.Brightness.AutoMode)
*pulFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO;
else
*pulFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
} else {
ERROR_LOG(("\'DCamGetProperty: Failed %x to read setting. Offset:%x\n", status, ulFieldOffset));
status = STATUS_UNSUCCESSFUL;
}
KeReleaseMutex(&pDevExt->hMutexProperty, FALSE);
return status;
}
NTSTATUS
DCamSetProperty(
IN PIRB pIrb,
PDCAM_EXTENSION pDevExt,
ULONG ulFieldOffset,
ULONG ulFlags,
LONG lValue,
DCamRegArea * pFeature,
DCamRegArea * pCachedRegArea
)
/*
For a supported device, set to a new setting.
*/
{
NTSTATUS status, StatusWait;
LONG lRetries = MAX_READ_REG_RETRIES;
LARGE_INTEGER stableTime;
// Make sure that device support this feature.
if(pFeature->Feature.PresenceInq == 0) {
DbgMsg1(("\'OffSet:%d not supported!\n", ulFieldOffset));
return STATUS_NOT_SUPPORTED;
}
// Validate the supported range
if((LONG) pFeature->Feature.MAX_Value < lValue || lValue < (LONG) pFeature->Feature.MIN_Value) {
ERROR_LOG(("\'Invalid value:%d for supported range (%d, %d)\n", lValue, pFeature->Feature.MIN_Value, pFeature->Feature.MAX_Value));
return STATUS_INVALID_PARAMETER;
}
// Serialize read/write to the register
StatusWait = KeWaitForSingleObject( &pDevExt->hMutexProperty, Executive, KernelMode, FALSE, 0 );
// Read the current setting of this property
pDevExt->RegArea.AsULONG = 0;
do {
status = DCamReadRegister(pIrb, pDevExt, ulFieldOffset, &(pDevExt->RegArea.AsULONG));
if (!status) {
pDevExt->RegArea.AsULONG = bswap(pDevExt->RegArea.AsULONG);
DbgMsg3(("\'SetProperty: Current: %x: Pres:%d;OnePush:%d;OnOff:%d;Auto:%d;Value:%d\n",
pDevExt->RegArea.AsULONG,
pDevExt->RegArea.Brightness.PresenceInq,
pDevExt->RegArea.Brightness.OnePush,
pDevExt->RegArea.Brightness.OnOff,
pDevExt->RegArea.Brightness.AutoMode,
pDevExt->RegArea.Brightness.Value
));
// This feature might be in the transition (such as zoom or focus),
// it might return pDevExt->RegArea.Brightness.PresenceInq == 0.
if(pDevExt->RegArea.Brightness.PresenceInq == 1)
break;
else {
if(lRetries > 1) {
stableTime.LowPart = DCAM_REG_STABLE_DELAY;
stableTime.HighPart = -1;
KeDelayExecutionThread(KernelMode, TRUE, &stableTime);
ERROR_LOG(("\'DCamSetProperty: delay, and try again...\n"));
};
}
} else {
// No need to retry if we failed to read.
break;
}
lRetries--;
} while (lRetries > 0);
if(status || lRetries == 0) {
KeReleaseMutex(&pDevExt->hMutexProperty, FALSE);
ERROR_LOG(("\'DCamSetProperty: Failed! ST:%x; exceeded retried while pres is still 0\n", status));
return STATUS_UNSUCCESSFUL;
}
pDevExt->RegArea.Brightness.PresenceInq = 1; // Should be present.
if((ulFlags & KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO) == KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO) {
pDevExt->RegArea.Brightness.AutoMode = 1;
// When Auto is set to 1, Value field is ignored.
} else {
pDevExt->RegArea.Brightness.AutoMode = 0;
// special case for white balance
if(FIELDOFFSET(CAMERA_REGISTER_MAP, WhiteBalance) == ulFieldOffset) {
pDevExt->RegArea.WhiteBalance.UValue = pDevExt->RegArea.WhiteBalance.VValue = lValue;
} else
pDevExt->RegArea.Brightness.Value = lValue;
}
DbgMsg2(("\'SetProperty: NewSetting: Offset:%d; %x; Pres:%d;OnePush:%d;OnOff:%d;Auto:%d;Value:%d\n",
ulFieldOffset,
pDevExt->RegArea.AsULONG,
pDevExt->RegArea.Brightness.PresenceInq,
pDevExt->RegArea.Brightness.OnePush,
pDevExt->RegArea.Brightness.OnOff,
pDevExt->RegArea.Brightness.AutoMode,
pDevExt->RegArea.Brightness.Value
));
pDevExt->RegArea.AsULONG = bswap(pDevExt->RegArea.AsULONG);
status = DCamWriteRegister(pIrb, pDevExt, ulFieldOffset, pDevExt->RegArea.AsULONG);
if(status) {
ERROR_LOG(("\'DCamGetProperty: failed with status=0x%x\n", status));
} else {
// Update the cached setting (saved in the device extension)
// These cached values will be save to registry as the persisted values for these properties.
if(pCachedRegArea) {
// WhiteBalance is an exception
if(FIELDOFFSET(CAMERA_REGISTER_MAP, WhiteBalance) == ulFieldOffset) {
pCachedRegArea->WhiteBalance.UValue = pCachedRegArea->WhiteBalance.VValue = lValue;
} else
pCachedRegArea->Brightness.Value = lValue;
// AutoMode is the 7th bit for all the properties used here. (we do not use TRIGGER_MODE)
pCachedRegArea->Brightness.AutoMode = ((ulFlags & KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO) == KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO);
}
#if DBG
// Verify that data were written as expected.
pDevExt->RegAreaVerify.AsULONG = 0;
status = DCamReadRegister(pIrb, pDevExt, ulFieldOffset, &(pDevExt->RegAreaVerify.AsULONG));
if (!status) {
// bswap so we can compare.
pDevExt->RegArea.AsULONG = bswap(pDevExt->RegArea.AsULONG);
pDevExt->RegAreaVerify.AsULONG = bswap(pDevExt->RegAreaVerify.AsULONG);
DbgMsg2(("\'SetProperty: VerifySetting; Offset:%d; %x; Pres:%d;OnePush:%d;OnOff:%d;Auto:%d;Value:%d\n\n",
ulFieldOffset,
pDevExt->RegAreaVerify.AsULONG,
pDevExt->RegAreaVerify.Brightness.PresenceInq,
pDevExt->RegAreaVerify.Brightness.OnePush,
pDevExt->RegAreaVerify.Brightness.OnOff,
pDevExt->RegAreaVerify.Brightness.AutoMode,
pDevExt->RegAreaVerify.Brightness.Value
));
ASSERT(pDevExt->RegArea.Brightness.PresenceInq == pDevExt->RegAreaVerify.Brightness.PresenceInq);
ASSERT(pDevExt->RegArea.Brightness.OnePush == pDevExt->RegAreaVerify.Brightness.OnePush);
ASSERT(pDevExt->RegArea.Brightness.OnOff == pDevExt->RegAreaVerify.Brightness.OnOff);
ASSERT(pDevExt->RegArea.Brightness.AutoMode == pDevExt->RegAreaVerify.Brightness.AutoMode);
// If not auto mode, Value must match!
ASSERT( pDevExt->RegArea.Brightness.Value == pDevExt->RegAreaVerify.Brightness.Value ||
(pDevExt->RegArea.Brightness.Value != pDevExt->RegAreaVerify.Brightness.Value && pDevExt->RegArea.Brightness.AutoMode == 1));
}
#endif
}
KeReleaseMutex(&pDevExt->hMutexProperty, FALSE);
return status;
}
/*
** AdapterGetVideoProcAmpProperty ()
**
** Handles Set operations on the VideoProcAmp property set.
** Testcap uses this for demo purposes only.
**
** Arguments:
**
** pSRB -
** Pointer to the HW_STREAM_REQUEST_BLOCK
**
** Returns:
**
** Side Effects: none
*/
VOID
AdapterGetVideoProcAmpProperty(
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
NTSTATUS status;
PDCAM_EXTENSION pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
PKSPROPERTY_VIDEOPROCAMP_S pS = (PKSPROPERTY_VIDEOPROCAMP_S) pSPD->PropertyInfo; // pointer to the data
ASSERT (pSPD->PropertyOutputSize >= sizeof (KSPROPERTY_VIDEOPROCAMP_S));
switch (pSPD->Property->Id) {
case KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Brightness), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_BRIGHTNESS].Feature);
break;
case KSPROPERTY_VIDEOPROCAMP_SHARPNESS:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Sharpness), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_SHARPNESS].Feature);
break;
case KSPROPERTY_VIDEOPROCAMP_HUE:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Hue), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_HUE].Feature);
break;
case KSPROPERTY_VIDEOPROCAMP_SATURATION:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Saturation), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_SATURATION].Feature);
break;
case KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, WhiteBalance), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_WHITEBALANCE].Feature);
break;
default:
DbgMsg2(("\'AdapterGetVideoProcAmpProperty, Id (%x)not supported.\n", pSPD->Property->Id));
ASSERT(FALSE);
status = STATUS_NOT_IMPLEMENTED;
break;
}
pSrb->Status = status;
pSrb->ActualBytesTransferred = sizeof (KSPROPERTY_VIDEOPROCAMP_S);
}
/*
** AdapterGetCameraControlProperty ()
**
** Handles Set operations on the VideoProcAmp property set.
** Testcap uses this for demo purposes only.
**
** Arguments:
**
** pSRB -
** Pointer to the HW_STREAM_REQUEST_BLOCK
**
** Returns:
**
** Side Effects: none
*/
VOID
AdapterGetCameraControlProperty(
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
NTSTATUS status;
PDCAM_EXTENSION pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
PKSPROPERTY_CAMERACONTROL_S pS = (PKSPROPERTY_CAMERACONTROL_S) pSPD->PropertyInfo; // pointer to the data
ASSERT (pSPD->PropertyOutputSize >= sizeof (KSPROPERTY_CAMERACONTROL_S));
switch (pSPD->Property->Id) {
case KSPROPERTY_CAMERACONTROL_FOCUS:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Focus), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_FOCUS].Feature);
break;
case KSPROPERTY_CAMERACONTROL_ZOOM:
status = DCamGetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Zoom), &pS->Value, &pS->Capabilities, &pS->Flags, &pDevExt->DevProperty[ENUM_ZOOM].Feature);
break;
default:
DbgMsg2(("\'AdapterGetCameraControlProperty, Id (%x)not supported.\n", pSPD->Property->Id));
ASSERT(FALSE);
status = STATUS_NOT_IMPLEMENTED;
break;
}
pSrb->Status = status;
pSrb->ActualBytesTransferred = sizeof (KSPROPERTY_CAMERACONTROL_S);
}
/*
** AdapterGetProperty ()
**
** Handles Get operations for all adapter properties.
**
** Arguments:
**
** pSRB -
** Pointer to the HW_STREAM_REQUEST_BLOCK
**
** Returns:
**
** Side Effects: none
*/
VOID
STREAMAPI
AdapterGetProperty(
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
if (IsEqualGUID(&PROPSETID_VIDCAP_VIDEOPROCAMP, &pSPD->Property->Set)) {
AdapterGetVideoProcAmpProperty (pSrb);
} else if (IsEqualGUID(&PROPSETID_VIDCAP_CAMERACONTROL, &pSPD->Property->Set)) {
AdapterGetCameraControlProperty (pSrb);
} else {
//
// We should never get here
//
ASSERT(FALSE);
}
}
/*
** AdapterSetVideoProcAmpProperty ()
**
** Handles Set operations on the VideoProcAmp property set.
** Testcap uses this for demo purposes only.
**
** Arguments:
**
** pSRB -
** Pointer to the HW_STREAM_REQUEST_BLOCK
**
** Returns:
**
** Side Effects: none
*/
VOID
AdapterSetVideoProcAmpProperty(
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
NTSTATUS status;
PDCAM_EXTENSION pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
PKSPROPERTY_VIDEOPROCAMP_S pS = (PKSPROPERTY_VIDEOPROCAMP_S) pSPD->PropertyInfo; // pointer to the data
ASSERT (pSPD->PropertyOutputSize >= sizeof (KSPROPERTY_VIDEOPROCAMP_S));
switch (pSPD->Property->Id) {
case KSPROPERTY_VIDEOPROCAMP_BRIGHTNESS:
status = DCamSetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Brightness), pS->Flags, pS->Value, &pDevExt->DevProperty[ENUM_BRIGHTNESS].Feature, &pDevExt->DevProperty[ENUM_BRIGHTNESS].StatusNControl);
break;
case KSPROPERTY_VIDEOPROCAMP_SHARPNESS:
status = DCamSetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Sharpness), pS->Flags, pS->Value, &pDevExt->DevProperty[ENUM_SHARPNESS].Feature, &pDevExt->DevProperty[ENUM_SHARPNESS].StatusNControl);
break;
case KSPROPERTY_VIDEOPROCAMP_HUE:
status = DCamSetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Hue), pS->Flags, pS->Value, &pDevExt->DevProperty[ENUM_HUE].Feature, &pDevExt->DevProperty[ENUM_HUE].StatusNControl);
break;
case KSPROPERTY_VIDEOPROCAMP_SATURATION:
status = DCamSetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Saturation), pS->Flags, pS->Value, &pDevExt->DevProperty[ENUM_SATURATION].Feature, &pDevExt->DevProperty[ENUM_SATURATION].StatusNControl);
break;
case KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE:
status = DCamSetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, WhiteBalance), pS->Flags, pS->Value, &pDevExt->DevProperty[ENUM_WHITEBALANCE].Feature, &pDevExt->DevProperty[ENUM_WHITEBALANCE].StatusNControl);
break;
default:
status = STATUS_NOT_IMPLEMENTED;
break;
}
pSrb->Status = status;
pSrb->ActualBytesTransferred = (status == STATUS_SUCCESS ? sizeof (KSPROPERTY_VIDEOPROCAMP_S) : 0);
}
/*
** AdapterSetCameraControlProperty ()
**
** Handles Set operations on the CameraControl property set.
**
** Arguments:
**
** pSRB -
** Pointer to the HW_STREAM_REQUEST_BLOCK
**
** Returns:
**
** Side Effects: none
*/
VOID
AdapterSetCameraControlProperty(
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
NTSTATUS status;
PDCAM_EXTENSION pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
PKSPROPERTY_CAMERACONTROL_S pS = (PKSPROPERTY_CAMERACONTROL_S) pSPD->PropertyInfo; // pointer to the data
ASSERT (pSPD->PropertyOutputSize >= sizeof (KSPROPERTY_CAMERACONTROL_S));
switch (pSPD->Property->Id) {
case KSPROPERTY_CAMERACONTROL_FOCUS:
status = DCamSetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Focus), pS->Flags, pS->Value, &pDevExt->DevProperty[ENUM_FOCUS].Feature, &pDevExt->DevProperty[ENUM_FOCUS].StatusNControl);
break;
case KSPROPERTY_CAMERACONTROL_ZOOM:
status = DCamSetProperty((PIRB) pSrb->SRBExtension, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Zoom), pS->Flags, pS->Value, &pDevExt->DevProperty[ENUM_ZOOM].Feature, &pDevExt->DevProperty[ENUM_ZOOM].StatusNControl);
break;
default:
status = STATUS_NOT_IMPLEMENTED;
break;
}
pSrb->Status = status;
pSrb->ActualBytesTransferred = (status == STATUS_SUCCESS ? sizeof (KSPROPERTY_CAMERACONTROL_S) : 0);
}
/*
** AdapterSetProperty ()
**
** Handles Get operations for all adapter properties.
**
** Arguments:
**
** pSRB -
** Pointer to the HW_STREAM_REQUEST_BLOCK
**
** Returns:
**
** Side Effects: none
*/
VOID
STREAMAPI
AdapterSetProperty(
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PSTREAM_PROPERTY_DESCRIPTOR pSPD = pSrb->CommandData.PropertyInfo;
if (IsEqualGUID(&PROPSETID_VIDCAP_VIDEOPROCAMP, &pSPD->Property->Set)) {
AdapterSetVideoProcAmpProperty (pSrb);
} else if (IsEqualGUID(&PROPSETID_VIDCAP_CAMERACONTROL, &pSPD->Property->Set)) {
AdapterSetCameraControlProperty (pSrb);
} else {
//
// We should never get here
//
ASSERT(FALSE);
}
}
NTSTATUS
CreateRegistryKeySingle(
IN HANDLE hKey,
IN ACCESS_MASK desiredAccess,
PWCHAR pwszSection,
OUT PHANDLE phKeySection
)
{
NTSTATUS status;
UNICODE_STRING ustr;
OBJECT_ATTRIBUTES objectAttributes;
RtlInitUnicodeString(&ustr, pwszSection);
InitializeObjectAttributes(
&objectAttributes,
&ustr,
OBJ_CASE_INSENSITIVE,
hKey,
NULL
);
status =
ZwCreateKey(
phKeySection,
desiredAccess,
&objectAttributes,
0,
NULL, /* optional*/
REG_OPTION_NON_VOLATILE,
NULL
);
return status;
}
NTSTATUS
CreateRegistrySubKey(
IN HANDLE hKey,
IN ACCESS_MASK desiredAccess,
PWCHAR pwszSection,
OUT PHANDLE phKeySection
)
{
UNICODE_STRING ustr;
USHORT usPos = 1; // Skip first backslash
static WCHAR wSep = '\\';
NTSTATUS status = STATUS_SUCCESS;
RtlInitUnicodeString(&ustr, pwszSection);
while(usPos < ustr.Length) {
if(ustr.Buffer[usPos] == wSep) {
// NULL terminate our partial string
ustr.Buffer[usPos] = UNICODE_NULL;
status =
CreateRegistryKeySingle(
hKey,
desiredAccess,
ustr.Buffer,
phKeySection
);
ustr.Buffer[usPos] = wSep;
if(NT_SUCCESS(status)) {
ZwClose(*phKeySection);
} else {
break;
}
}
usPos++;
}
// Create the full key
if(NT_SUCCESS(status)) {
status =
CreateRegistryKeySingle(
hKey,
desiredAccess,
ustr.Buffer,
phKeySection
);
}
return status;
}
NTSTATUS
GetRegistryKeyValue (
IN HANDLE Handle,
IN PWCHAR KeyNameString,
IN ULONG KeyNameStringLength,
IN PVOID Data,
IN PULONG DataLength
)
/*++
Routine Description:
This routine gets the specified value out of the registry
Arguments:
Handle - Handle to location in registry
KeyNameString - registry key we're looking for
KeyNameStringLength - length of registry key we're looking for
Data - where to return the data
DataLength - how big the data is
Return Value:
status is returned from ZwQueryValueKey
--*/
{
NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES;
UNICODE_STRING keyName;
ULONG length;
PKEY_VALUE_FULL_INFORMATION fullInfo;
RtlInitUnicodeString(&keyName, KeyNameString);
length = sizeof(KEY_VALUE_FULL_INFORMATION) +
KeyNameStringLength + *DataLength;
fullInfo = ExAllocatePool(PagedPool, length);
if (fullInfo) {
status = ZwQueryValueKey(
Handle,
&keyName,
KeyValueFullInformation,
fullInfo,
length,
&length
);
if (NT_SUCCESS(status)){
ASSERT(fullInfo->DataLength <= *DataLength);
RtlCopyMemory(
Data,
((PUCHAR) fullInfo) + fullInfo->DataOffset,
fullInfo->DataLength
);
}
*DataLength = fullInfo->DataLength;
ExFreePool(fullInfo);
}
return (status);
}
NTSTATUS
SetRegistryKeyValue(
HANDLE hKey,
PWCHAR pwszEntry,
LONG nValue
)
{
NTSTATUS status;
UNICODE_STRING ustr;
RtlInitUnicodeString(&ustr, pwszEntry);
status =
ZwSetValueKey(
hKey,
&ustr,
0, /* optional */
REG_DWORD,
&nValue,
sizeof(nValue)
);
return status;
}
BOOL
DCamQueryPropertyFeaturesAndSettings(
IN PIRB pIrb,
PDCAM_EXTENSION pDevExt,
ULONG ulFieldOffset,
DCamRegArea * pFeature,
HANDLE hKeySettings,
PWCHAR pwszPropertyName,
ULONG ulPropertyNameLen,
DCamRegArea * pPropertySettings,
PWCHAR pwszPropertyNameDef,
ULONG ulPropertyNameDefLen,
LONG * plValueDef
)
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG ulLength;
DCamRegArea RegDefault;
// Reset settings.
pFeature->AsULONG = 0;
pPropertySettings->AsULONG = 0;
// Read feature of this property
Status = DCamReadRegister(pIrb, pDevExt, ulFieldOffset-QUERY_ADDR_OFFSET, &(pFeature->AsULONG));
if(NT_SUCCESS(Status)) {
pFeature->AsULONG = bswap(pFeature->AsULONG);
if(pFeature->Feature.PresenceInq == 0) {
ERROR_LOG(("\'%S not supported; Reset property settings\n", pwszPropertyName));
return FALSE;
}
} else {
ERROR_LOG(("\'ST:%x reading register\n", Status));
return FALSE;
}
// Get persisted settings saved in the registry; (if it not defined, it is initialize to 0).
ulLength = sizeof(LONG);
Status = GetRegistryKeyValue(
hKeySettings,
pwszPropertyName,
ulPropertyNameLen,
(PVOID) pPropertySettings,
&ulLength
);
if(NT_SUCCESS(Status)) {
// Detect if AutoMode was mistakenly set by the registry.
if(pPropertySettings->Brightness.AutoMode == 1 && pFeature->Feature.AutoMode == 0) {
ERROR_LOG(("\'Detect %s AutoMode mistakenly set\n", pwszPropertyName));
pPropertySettings->Brightness.AutoMode = 0;
}
// Detect out of range and set it to mid range.
if(pPropertySettings->Brightness.Value < pFeature->Feature.MIN_Value ||
pFeature->Feature.MAX_Value < pPropertySettings->Brightness.Value) {
ERROR_LOG(("\'Detect %S out of range %d not within (%d,%d)\n",
pwszPropertyName,
pPropertySettings->Brightness.Value,
pFeature->Feature.MIN_Value,
pFeature->Feature.MAX_Value));
pPropertySettings->Brightness.Value = (pFeature->Feature.MIN_Value + pFeature->Feature.MAX_Value)/2;
}
// Query default value
ulLength = sizeof(LONG);
RegDefault.AsULONG = 0;
*plValueDef = 0;
Status = GetRegistryKeyValue(
hKeySettings,
pwszPropertyNameDef,
ulPropertyNameDefLen,
(PVOID) &RegDefault,
&ulLength
);
if(NT_SUCCESS(Status)) {
// Make sure that the default is within the range
if(RegDefault.Brightness.Value < pFeature->Feature.MIN_Value ||
pFeature->Feature.MAX_Value < RegDefault.Brightness.Value) {
ERROR_LOG(("\'%S %d out of range (%d, %d), set to midrange.\n",
pwszPropertyNameDef,
RegDefault.Brightness.Value,
pFeature->Feature.MIN_Value,
pFeature->Feature.MAX_Value));
*plValueDef = (LONG) (pFeature->Feature.MIN_Value + pFeature->Feature.MAX_Value)/2;
} else {
*plValueDef = (LONG) RegDefault.Brightness.Value;
}
} else {
ERROR_LOG(("\'Read Registry failed! ST:%x; %S; Offset:%d\n", Status, pwszPropertyNameDef, ulFieldOffset));
*plValueDef = (LONG) (pFeature->Feature.MIN_Value + pFeature->Feature.MAX_Value)/2;
// Set default so return success too.
Status = STATUS_SUCCESS;
}
} else {
// If registry key is not in the registry key, we will initialize it to
// always use the auto mode, and its value (and the default) in midrange.
ERROR_LOG(("\'Read Registry failed! ST:%x; %S; Offset:%d\n", Status, pwszPropertyName, ulFieldOffset));
pPropertySettings->Brightness.AutoMode = pFeature->Feature.AutoMode;
pPropertySettings->Brightness.Value = (pFeature->Feature.MIN_Value + pFeature->Feature.MAX_Value)/2;
*plValueDef = (LONG) (pFeature->Feature.MIN_Value + pFeature->Feature.MAX_Value)/2;
// Set default so return success too.
Status = STATUS_SUCCESS;
}
#if DBG
// Print out a summary of this property setting, include:
// Features, current setting, and persisted values.
DCamReadRegister(pIrb, pDevExt, ulFieldOffset, &(pDevExt->RegArea.AsULONG));
pDevExt->RegArea.AsULONG = bswap(pDevExt->RegArea.AsULONG);
DbgMsg1(("\'***** St:%x; %S (offset:%d)\n", Status, pwszPropertyName, ulFieldOffset));
DbgMsg1(("\'Feature: %x; Pres:%d; OnePush:%d; ReadOut:%d; OnOff;%d; (A:%d; M:%d); (%d..%d)\n",
pFeature->AsULONG,
pFeature->Feature.PresenceInq,
pFeature->Feature.OnePush,
pFeature->Feature.ReadOut_Inq,
pFeature->Feature.OnOff,
pFeature->Feature.AutoMode,
pFeature->Feature.ManualMode,
pFeature->Feature.MIN_Value,
pFeature->Feature.MAX_Value
));
DbgMsg1(("\'Setting: %.8x; Pres:%d; OnePush:%d; OnOff;%d; Auto:%d; (%d;%d)\n",
pDevExt->RegArea.AsULONG,
pDevExt->RegArea.WhiteBalance.PresenceInq,
pDevExt->RegArea.WhiteBalance.OnePush,
pDevExt->RegArea.WhiteBalance.OnOff,
pDevExt->RegArea.WhiteBalance.AutoMode,
pDevExt->RegArea.WhiteBalance.UValue,
pDevExt->RegArea.WhiteBalance.VValue
));
DbgMsg1(("\'Registry:%.8x; Pres:%d; OnePush:%d; OnOff;%d; Auto:%d; (%d;%d)\n\n",
pPropertySettings->AsULONG,
pPropertySettings->WhiteBalance.PresenceInq,
pPropertySettings->WhiteBalance.OnePush,
pPropertySettings->WhiteBalance.OnOff,
pPropertySettings->WhiteBalance.AutoMode,
pPropertySettings->WhiteBalance.UValue,
pPropertySettings->WhiteBalance.VValue
));
#endif
return NT_SUCCESS(Status);
}
BOOL
DCamGetPropertyValuesFromRegistry(
PDCAM_EXTENSION pDevExt
)
{
NTSTATUS Status;
HANDLE hPDOKey, hKeySettings;
PIRB pIrb;
ULONG ulLength;
DbgMsg2(("\'GetPropertyValuesFromRegistry: pDevExt=%x; pDevExt->BusDeviceObject=%x\n", pDevExt, pDevExt->BusDeviceObject));
pIrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(IRB), 'macd');
if(!pIrb)
return FALSE;
//
// Registry key:
// Windows 2000:
// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
// {6BDD1FC6-810F-11D0-BEC7-08002BE2092F\000x
//
// Win98:
// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Class\Image\000x
//
Status =
IoOpenDeviceRegistryKey(
pDevExt->PhysicalDeviceObject,
PLUGPLAY_REGKEY_DRIVER,
STANDARD_RIGHTS_READ,
&hPDOKey);
// Can fail only if PDO might be deleted due to device removal.
ASSERT(!pDevExt->bDevRemoved && Status == STATUS_SUCCESS);
//
// loop through our table of strings,
// reading the registry for each.
//
if(!NT_SUCCESS(Status)) {
ERROR_LOG(("\'GetPropertyValuesFromRegistry: IoOpenDeviceRegistryKey failed with Status=%x\n", Status));
ExFreePool(pIrb); pIrb = NULL;
return FALSE;
}
//
// Create or open the settings key
//
Status =
CreateRegistrySubKey(
hPDOKey,
KEY_ALL_ACCESS,
wszSettings,
&hKeySettings
);
if(!NT_SUCCESS(Status)) {
ERROR_LOG(("\'GetPropertyValuesFromRegistry: CreateRegistrySubKey failed with Status=%x\n", Status));
ZwClose(hPDOKey);
return FALSE;
}
// Get persisted settings saved in the registry; (if it not defined, it is initialize to 0).
//
// Read from registry to find out what compression formats are supported
// by the decoder installed on this system. This registry key can be altered
// if IHV/ISV add additional decoder. Currently, Microsft's MSYUV supports
// only UYVY format.
//
pDevExt->DecoderDCamVModeInq0.AsULONG = 0;
ulLength = sizeof(LONG);
Status = GetRegistryKeyValue(
hKeySettings,
wszVModeInq0,
sizeof(wszVModeInq0),
(PVOID) &pDevExt->DecoderDCamVModeInq0,
&ulLength
);
if(NT_SUCCESS(Status)) {
pDevExt->DecoderDCamVModeInq0.AsULONG = bswap(pDevExt->DecoderDCamVModeInq0.AsULONG);
DbgMsg1(("\'Modes supported by the decoder: %x\n [0]:%d\n [1]:%d\n [2]:%d\n [3]:%d\n [4]:%d\n [5]:%d\n",
pDevExt->DecoderDCamVModeInq0.AsULONG,
pDevExt->DecoderDCamVModeInq0.VMode.Mode0,
pDevExt->DecoderDCamVModeInq0.VMode.Mode1,
pDevExt->DecoderDCamVModeInq0.VMode.Mode2,
pDevExt->DecoderDCamVModeInq0.VMode.Mode3,
pDevExt->DecoderDCamVModeInq0.VMode.Mode4,
pDevExt->DecoderDCamVModeInq0.VMode.Mode5
));
} else {
ERROR_LOG(("\'Failed to read VModeInq0 registery: %x\n", Status));
}
// MSYUV supports these modes; always turn them on.
pDevExt->DecoderDCamVModeInq0.VMode.Mode1 = 1; // MSYUV.dll:(UYVY:320x480)
pDevExt->DecoderDCamVModeInq0.VMode.Mode3 = 1; // MSYUV.dll:(UYVY:640x480)
#ifdef SUPPORT_RGB24
pDevExt->DecoderDCamVModeInq0.VMode.Mode4 = 1; // MSYUV.dll:(RGB24:640x480)
#endif
#if DBG
pDevExt->DevFeature1.AsULONG = 0;
Status = DCamReadRegister(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, FeaturePresent1), &pDevExt->DevFeature1.AsULONG);
if(NT_SUCCESS(Status)) {
pDevExt->DevFeature1.AsULONG = bswap(pDevExt->DevFeature1.AsULONG);
DbgMsg1(("\'Features1: %x:\n Brightness:%d;\n Exposure:%d\n Sharpness:%d\n WhiteBalance:%d\n Hue:%d;\n Saturation:%d;\n Gamma:%d\n Shutter:%d\n Gain:%d\n Iris:%d\n Focus:%d\n",
pDevExt->DevFeature1.AsULONG,
pDevExt->DevFeature1.CameraCap1.Brightness,
pDevExt->DevFeature1.CameraCap1.Exposure,
pDevExt->DevFeature1.CameraCap1.Sharpness,
pDevExt->DevFeature1.CameraCap1.White_Balance,
pDevExt->DevFeature1.CameraCap1.Hue,
pDevExt->DevFeature1.CameraCap1.Saturation,
pDevExt->DevFeature1.CameraCap1.Gamma,
pDevExt->DevFeature1.CameraCap1.Shutter,
pDevExt->DevFeature1.CameraCap1.Gain,
pDevExt->DevFeature1.CameraCap1.Iris,
pDevExt->DevFeature1.CameraCap1.Focus
));
} else {
ERROR_LOG(("\'Failed to read Feature1 register: %x\n", Status));
}
pDevExt->DevFeature2.AsULONG = 0;
Status = DCamReadRegister(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, FeaturePresent2), &pDevExt->DevFeature1.AsULONG);
if(NT_SUCCESS(Status)) {
pDevExt->DevFeature2.AsULONG = bswap(pDevExt->DevFeature2.AsULONG);
DbgMsg1(("\'Features2: %x\n Zoom:%d\n Pan:%d\n Tile:%d\n",
pDevExt->DevFeature2.AsULONG,
pDevExt->DevFeature2.CameraCap2.Zoom,
pDevExt->DevFeature2.CameraCap2.Pan,
pDevExt->DevFeature1.CameraCap2.Tile
));
} else {
ERROR_LOG(("\'Failed to read Feature2 register: %x\n", Status));
}
#endif
// Brightness
if(DCamQueryPropertyFeaturesAndSettings(
pIrb,
pDevExt,
FIELDOFFSET(CAMERA_REGISTER_MAP, Brightness),
&pDevExt->DevProperty[ENUM_BRIGHTNESS].Feature,
hKeySettings,
wszBrightness,
sizeof(wszBrightness),
&pDevExt->DevProperty[ENUM_BRIGHTNESS].StatusNControl,
wszBrightnessDef,
sizeof(wszBrightnessDef),
&pDevExt->DevProperty[ENUM_BRIGHTNESS].DefaultValue
)) {
pDevExt->DevProperty[ENUM_BRIGHTNESS].RangeNStep.Bounds.SignedMinimum = pDevExt->DevProperty[ENUM_BRIGHTNESS].Feature.Feature.MIN_Value;
pDevExt->DevProperty[ENUM_BRIGHTNESS].RangeNStep.Bounds.SignedMaximum = pDevExt->DevProperty[ENUM_BRIGHTNESS].Feature.Feature.MAX_Value;
pDevExt->DevPropDefine[ENUM_BRIGHTNESS].Range.Members = (VOID*) &pDevExt->DevProperty[ENUM_BRIGHTNESS].RangeNStep;
pDevExt->DevPropDefine[ENUM_BRIGHTNESS].Default.Members = (VOID*) &pDevExt->DevProperty[ENUM_BRIGHTNESS].DefaultValue;
} else {
pDevExt->VideoProcAmpItems[ENUM_BRIGHTNESS].GetSupported = FALSE;
pDevExt->VideoProcAmpItems[ENUM_BRIGHTNESS].SetSupported = FALSE;
}
// Saturation
if(DCamQueryPropertyFeaturesAndSettings(
pIrb,
pDevExt,
FIELDOFFSET(CAMERA_REGISTER_MAP, Saturation),
&pDevExt->DevProperty[ENUM_SATURATION].Feature,
hKeySettings,
wszSaturation,
sizeof(wszSaturation),
&pDevExt->DevProperty[ENUM_SATURATION].StatusNControl,
wszSaturationDef,
sizeof(wszSaturationDef),
&pDevExt->DevProperty[ENUM_SATURATION].DefaultValue
)) {
pDevExt->DevProperty[ENUM_SATURATION].RangeNStep.Bounds.SignedMinimum = pDevExt->DevProperty[ENUM_SATURATION].Feature.Feature.MIN_Value;
pDevExt->DevProperty[ENUM_SATURATION].RangeNStep.Bounds.SignedMaximum = pDevExt->DevProperty[ENUM_SATURATION].Feature.Feature.MAX_Value;
pDevExt->DevPropDefine[ENUM_SATURATION].Range.Members = (VOID*) &pDevExt->DevProperty[ENUM_SATURATION].RangeNStep;
pDevExt->DevPropDefine[ENUM_SATURATION].Default.Members = (VOID*) &pDevExt->DevProperty[ENUM_SATURATION].DefaultValue;
} else {
pDevExt->VideoProcAmpItems[ENUM_SATURATION].GetSupported = FALSE;
pDevExt->VideoProcAmpItems[ENUM_SATURATION].SetSupported = FALSE;
}
// Hue
if(DCamQueryPropertyFeaturesAndSettings(
pIrb,
pDevExt,
FIELDOFFSET(CAMERA_REGISTER_MAP, Hue),
&pDevExt->DevProperty[ENUM_HUE].Feature,
hKeySettings,
wszHue,
sizeof(wszHue),
&pDevExt->DevProperty[ENUM_HUE].StatusNControl,
wszHueDef,
sizeof(wszHueDef),
&pDevExt->DevProperty[ENUM_HUE].DefaultValue
)) {
pDevExt->DevProperty[ENUM_HUE].RangeNStep.Bounds.SignedMinimum = pDevExt->DevProperty[ENUM_HUE].Feature.Feature.MIN_Value;
pDevExt->DevProperty[ENUM_HUE].RangeNStep.Bounds.SignedMaximum = pDevExt->DevProperty[ENUM_HUE].Feature.Feature.MAX_Value;
pDevExt->DevPropDefine[ENUM_HUE].Range.Members = (VOID*) &pDevExt->DevProperty[ENUM_HUE].RangeNStep;
pDevExt->DevPropDefine[ENUM_HUE].Default.Members = (VOID*) &pDevExt->DevProperty[ENUM_HUE].DefaultValue;
} else {
pDevExt->VideoProcAmpItems[ENUM_HUE].GetSupported = FALSE;
pDevExt->VideoProcAmpItems[ENUM_HUE].SetSupported = FALSE;
}
// Sharpness
if(DCamQueryPropertyFeaturesAndSettings(
pIrb,
pDevExt,
FIELDOFFSET(CAMERA_REGISTER_MAP, Sharpness),
&pDevExt->DevProperty[ENUM_SHARPNESS].Feature,
hKeySettings,
wszSharpness,
sizeof(wszSharpness),
&pDevExt->DevProperty[ENUM_SHARPNESS].StatusNControl,
wszSharpnessDef,
sizeof(wszSharpnessDef),
&pDevExt->DevProperty[ENUM_SHARPNESS].DefaultValue
)) {
pDevExt->DevProperty[ENUM_SHARPNESS].RangeNStep.Bounds.SignedMinimum = pDevExt->DevProperty[ENUM_SHARPNESS].Feature.Feature.MIN_Value;
pDevExt->DevProperty[ENUM_SHARPNESS].RangeNStep.Bounds.SignedMaximum = pDevExt->DevProperty[ENUM_SHARPNESS].Feature.Feature.MAX_Value;
pDevExt->DevPropDefine[ENUM_SHARPNESS].Range.Members = (VOID*) &pDevExt->DevProperty[ENUM_SHARPNESS].RangeNStep;
pDevExt->DevPropDefine[ENUM_SHARPNESS].Default.Members = (VOID*) &pDevExt->DevProperty[ENUM_SHARPNESS].DefaultValue;
} else {
pDevExt->VideoProcAmpItems[ENUM_SHARPNESS].GetSupported = FALSE;
pDevExt->VideoProcAmpItems[ENUM_SHARPNESS].SetSupported = FALSE;
}
// WhiteBalance
if(DCamQueryPropertyFeaturesAndSettings(
pIrb,
pDevExt,
FIELDOFFSET(CAMERA_REGISTER_MAP, WhiteBalance),
&pDevExt->DevProperty[ENUM_WHITEBALANCE].Feature,
hKeySettings,
wszWhiteBalance,
sizeof(wszWhiteBalance),
&pDevExt->DevProperty[ENUM_WHITEBALANCE].StatusNControl,
wszWhiteBalanceDef,
sizeof(wszWhiteBalanceDef),
&pDevExt->DevProperty[ENUM_WHITEBALANCE].DefaultValue
)) {
pDevExt->DevProperty[ENUM_WHITEBALANCE].RangeNStep.Bounds.SignedMinimum = pDevExt->DevProperty[ENUM_WHITEBALANCE].Feature.Feature.MIN_Value;
pDevExt->DevProperty[ENUM_WHITEBALANCE].RangeNStep.Bounds.SignedMaximum = pDevExt->DevProperty[ENUM_WHITEBALANCE].Feature.Feature.MAX_Value;
pDevExt->DevPropDefine[ENUM_WHITEBALANCE].Range.Members = (VOID*) &pDevExt->DevProperty[ENUM_WHITEBALANCE].RangeNStep;
pDevExt->DevPropDefine[ENUM_WHITEBALANCE].Default.Members = (VOID*) &pDevExt->DevProperty[ENUM_WHITEBALANCE].DefaultValue;
} else {
pDevExt->VideoProcAmpItems[ENUM_WHITEBALANCE].GetSupported = FALSE;
pDevExt->VideoProcAmpItems[ENUM_WHITEBALANCE].SetSupported = FALSE;
}
// Zoom
if(DCamQueryPropertyFeaturesAndSettings(
pIrb,
pDevExt,
FIELDOFFSET(CAMERA_REGISTER_MAP, Zoom),
&pDevExt->DevProperty[ENUM_ZOOM].Feature,
hKeySettings,
wszZoom,
sizeof(wszZoom),
&pDevExt->DevProperty[ENUM_ZOOM].StatusNControl,
wszZoomDef,
sizeof(wszZoomDef),
&pDevExt->DevProperty[ENUM_ZOOM].DefaultValue
)) {
pDevExt->DevProperty[ENUM_ZOOM].RangeNStep.Bounds.SignedMinimum = pDevExt->DevProperty[ENUM_ZOOM].Feature.Feature.MIN_Value;
pDevExt->DevProperty[ENUM_ZOOM].RangeNStep.Bounds.SignedMaximum = pDevExt->DevProperty[ENUM_ZOOM].Feature.Feature.MAX_Value;
pDevExt->DevPropDefine[ENUM_ZOOM].Range.Members = (VOID*) &pDevExt->DevProperty[ENUM_ZOOM].RangeNStep;
pDevExt->DevPropDefine[ENUM_ZOOM].Default.Members = (VOID*) &pDevExt->DevProperty[ENUM_ZOOM].DefaultValue;
} else {
pDevExt->VideoProcAmpItems[ENUM_ZOOM].GetSupported = FALSE;
pDevExt->VideoProcAmpItems[ENUM_ZOOM].SetSupported = FALSE;
}
// Focus
if(DCamQueryPropertyFeaturesAndSettings(
pIrb,
pDevExt,
FIELDOFFSET(CAMERA_REGISTER_MAP, Focus),
&pDevExt->DevProperty[ENUM_FOCUS].Feature,
hKeySettings,
wszFocus,
sizeof(wszFocus),
&pDevExt->DevProperty[ENUM_FOCUS].StatusNControl,
wszFocusDef,
sizeof(wszFocusDef),
&pDevExt->DevProperty[ENUM_FOCUS].DefaultValue
)) {
pDevExt->DevProperty[ENUM_FOCUS].RangeNStep.Bounds.SignedMinimum = pDevExt->DevProperty[ENUM_FOCUS].Feature.Feature.MIN_Value;
pDevExt->DevProperty[ENUM_FOCUS].RangeNStep.Bounds.SignedMaximum = pDevExt->DevProperty[ENUM_FOCUS].Feature.Feature.MAX_Value;
pDevExt->DevPropDefine[ENUM_FOCUS].Range.Members = (VOID*) &pDevExt->DevProperty[ENUM_FOCUS].RangeNStep;
pDevExt->DevPropDefine[ENUM_FOCUS].Default.Members = (VOID*) &pDevExt->DevProperty[ENUM_FOCUS].DefaultValue;
} else {
pDevExt->VideoProcAmpItems[ENUM_FOCUS].GetSupported = FALSE;
pDevExt->VideoProcAmpItems[ENUM_FOCUS].SetSupported = FALSE;
}
ZwClose(hKeySettings);
ZwClose(hPDOKey);
ExFreePool(pIrb); pIrb = NULL;
return TRUE;
}
BOOL
DCamSetPropertyValuesToRegistry(
PDCAM_EXTENSION pDevExt
)
{
// Set the default to :
// HLM\Software\DeviceExtension->pchVendorName\1394DCam
NTSTATUS Status;
HANDLE hPDOKey, hKeySettings;
DbgMsg2(("\'SetPropertyValuesToRegistry: pDevExt=%x; pDevExt->BusDeviceObject=%x\n", pDevExt, pDevExt->BusDeviceObject));
//
// Registry key:
// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
// {6BDD1FC6-810F-11D0-BEC7-08002BE2092F\000x
//
Status =
IoOpenDeviceRegistryKey(
pDevExt->PhysicalDeviceObject,
PLUGPLAY_REGKEY_DRIVER,
STANDARD_RIGHTS_WRITE,
&hPDOKey);
// PDO might be deleted when it was removed.
if(! pDevExt->bDevRemoved) {
ASSERT(Status == STATUS_SUCCESS);
}
//
// reading the feature and registry setting for each property
//
if(NT_SUCCESS(Status)) {
// Create or open the settings key
Status =
CreateRegistrySubKey(
hPDOKey,
KEY_ALL_ACCESS,
wszSettings,
&hKeySettings
);
if(NT_SUCCESS(Status)) {
// Brightness
Status = SetRegistryKeyValue(
hKeySettings,
wszBrightness,
pDevExt->DevProperty[ENUM_BRIGHTNESS].StatusNControl.AsULONG);
DbgMsg2(("\'SetPropertyValuesToRegistry: Status %x, Brightness %d\n", Status, pDevExt->DevProperty[ENUM_BRIGHTNESS].StatusNControl.AsULONG));
// Hue
Status = SetRegistryKeyValue(
hKeySettings,
wszHue,
pDevExt->DevProperty[ENUM_HUE].StatusNControl.AsULONG);
DbgMsg2(("\'SetPropertyValuesToRegistry: Status %x, Hue %d\n", Status, pDevExt->DevProperty[ENUM_HUE].StatusNControl.AsULONG));
// Saturation
Status = SetRegistryKeyValue(
hKeySettings,
wszSaturation,
pDevExt->DevProperty[ENUM_SATURATION].StatusNControl.AsULONG);
DbgMsg2(("\'SetPropertyValuesToRegistry: Status %x, Saturation %d\n", Status, pDevExt->DevProperty[ENUM_SATURATION].StatusNControl.AsULONG));
// Sharpness
Status = SetRegistryKeyValue(
hKeySettings,
wszSharpness,
pDevExt->DevProperty[ENUM_SHARPNESS].StatusNControl.AsULONG);
DbgMsg2(("\'SetPropertyValuesToRegistry: Status %x, Sharpness %d\n", Status, pDevExt->DevProperty[ENUM_SHARPNESS].StatusNControl.AsULONG));
// WhiteBalance
Status = SetRegistryKeyValue(
hKeySettings,
wszWhiteBalance,
pDevExt->DevProperty[ENUM_WHITEBALANCE].StatusNControl.AsULONG);
DbgMsg2(("\'SetPropertyValuesToRegistry: Status %x, WhiteBalance %d\n", Status, pDevExt->DevProperty[ENUM_WHITEBALANCE].StatusNControl.AsULONG));
// Zoom
Status = SetRegistryKeyValue(
hKeySettings,
wszZoom,
pDevExt->DevProperty[ENUM_ZOOM].StatusNControl.AsULONG);
DbgMsg2(("\'SetPropertyValuesToRegistry: Status %x, Zoom %d\n", Status, pDevExt->DevProperty[ENUM_ZOOM].StatusNControl.AsULONG));
// Focus
Status = SetRegistryKeyValue(
hKeySettings,
wszFocus,
pDevExt->DevProperty[ENUM_FOCUS].StatusNControl.AsULONG);
DbgMsg2(("\'SetPropertyValuesToRegistry: Status %x, Focus %d\n", Status, pDevExt->DevProperty[ENUM_FOCUS].StatusNControl.AsULONG));
ZwClose(hKeySettings);
ZwClose(hPDOKey);
return TRUE;
} else {
ERROR_LOG(("\'SetPropertyValuesToRegistry: CreateRegistrySubKey failed with Status=%x\n", Status));
}
ZwClose(hPDOKey);
} else {
DbgMsg2(("\'SetPropertyValuesToRegistry: IoOpenDeviceRegistryKey failed with Status=%x\n", Status));
}
return FALSE;
}
VOID
SetCurrentDevicePropertyValues(
PDCAM_EXTENSION pDevExt,
PIRB pIrb
)
{
ULONG ulFlags;
// Set to the last saved values or the defaults
// VideoProcAmp
ulFlags = pDevExt->DevProperty[ENUM_BRIGHTNESS].StatusNControl.Brightness.AutoMode ? KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO : KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
DCamSetProperty(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Brightness), ulFlags, pDevExt->DevProperty[ENUM_BRIGHTNESS].StatusNControl.Brightness.Value, &pDevExt->DevProperty[ENUM_BRIGHTNESS].Feature, &pDevExt->DevProperty[ENUM_BRIGHTNESS].StatusNControl);
ulFlags = pDevExt->DevProperty[ENUM_HUE].StatusNControl.Brightness.AutoMode ? KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO : KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
DCamSetProperty(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Hue), ulFlags, pDevExt->DevProperty[ENUM_HUE].StatusNControl.Brightness.Value, &pDevExt->DevProperty[ENUM_HUE].Feature, &pDevExt->DevProperty[ENUM_HUE].StatusNControl);
ulFlags = pDevExt->DevProperty[ENUM_SATURATION].StatusNControl.Brightness.AutoMode ? KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO : KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
DCamSetProperty(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Saturation), ulFlags, pDevExt->DevProperty[ENUM_SATURATION].StatusNControl.Brightness.Value, &pDevExt->DevProperty[ENUM_SATURATION].Feature, &pDevExt->DevProperty[ENUM_SATURATION].StatusNControl);
ulFlags = pDevExt->DevProperty[ENUM_SHARPNESS].StatusNControl.Brightness.AutoMode ? KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO : KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
DCamSetProperty(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Sharpness), ulFlags, pDevExt->DevProperty[ENUM_SHARPNESS].StatusNControl.Brightness.Value, &pDevExt->DevProperty[ENUM_SHARPNESS].Feature, &pDevExt->DevProperty[ENUM_SHARPNESS].StatusNControl);
ulFlags = pDevExt->DevProperty[ENUM_WHITEBALANCE].StatusNControl.Brightness.AutoMode ? KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO : KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
DCamSetProperty(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, WhiteBalance),ulFlags, pDevExt->DevProperty[ENUM_WHITEBALANCE].StatusNControl.WhiteBalance.UValue, &pDevExt->DevProperty[ENUM_WHITEBALANCE].Feature, &pDevExt->DevProperty[ENUM_WHITEBALANCE].StatusNControl);
// CameraControl
ulFlags = pDevExt->DevProperty[ENUM_ZOOM].StatusNControl.Brightness.AutoMode ? KSPROPERTY_CAMERACONTROL_FLAGS_AUTO : KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
DCamSetProperty(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Zoom), ulFlags, pDevExt->DevProperty[ENUM_ZOOM].StatusNControl.Brightness.Value, &pDevExt->DevProperty[ENUM_ZOOM].Feature, &pDevExt->DevProperty[ENUM_ZOOM].StatusNControl);
ulFlags = pDevExt->DevProperty[ENUM_FOCUS].StatusNControl.Brightness.AutoMode ? KSPROPERTY_CAMERACONTROL_FLAGS_AUTO : KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
DCamSetProperty(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, Focus), ulFlags, pDevExt->DevProperty[ENUM_FOCUS].StatusNControl.Brightness.Value, &pDevExt->DevProperty[ENUM_FOCUS].Feature, &pDevExt->DevProperty[ENUM_FOCUS].StatusNControl);
}
BOOL
DCamPrepareDevProperties(
PDCAM_EXTENSION pDevExt
)
/*
Contruct the property table and initialize them to the default value.
*/
{
// Initialize property settings (part of the Device Extension)
// Property Sets: VideoProcAmp and CameraControl sets
pDevExt->ulPropSetSupported = NUMBER_OF_ADAPTER_PROPERTY_SETS;
RtlCopyMemory(&pDevExt->VideoProcAmpSet, AdapterPropertyTable, sizeof(KSPROPERTY_SET) * NUMBER_OF_ADAPTER_PROPERTY_SETS);
pDevExt->VideoProcAmpSet.PropertyItem = &pDevExt->VideoProcAmpItems[0];
pDevExt->CameraControlSet.PropertyItem = &pDevExt->CameraControlItems[0];
// Property Items, VideoProcAmp and CameraControl Items
RtlCopyMemory(&pDevExt->VideoProcAmpItems, VideoProcAmpProperties, sizeof(KSPROPERTY_ITEM) * NUM_VIDEOPROCAMP_ITEMS);
RtlCopyMemory(&pDevExt->CameraControlItems, CameraControlProperties, sizeof(KSPROPERTY_ITEM) * NUM_CAMERACONTROL_ITEMS);
// Property values and it member lists (range and default)
pDevExt->VideoProcAmpItems[ENUM_BRIGHTNESS].Values = &pDevExt->DevPropDefine[ENUM_BRIGHTNESS].Value;
pDevExt->VideoProcAmpItems[ENUM_SHARPNESS].Values = &pDevExt->DevPropDefine[ENUM_SHARPNESS].Value;
pDevExt->VideoProcAmpItems[ENUM_HUE].Values = &pDevExt->DevPropDefine[ENUM_HUE].Value;
pDevExt->VideoProcAmpItems[ENUM_SATURATION].Values = &pDevExt->DevPropDefine[ENUM_SATURATION].Value;
pDevExt->VideoProcAmpItems[ENUM_WHITEBALANCE].Values = &pDevExt->DevPropDefine[ENUM_WHITEBALANCE].Value;
//
pDevExt->VideoProcAmpItems[ENUM_FOCUS].Values = &pDevExt->DevPropDefine[ENUM_FOCUS].Value;
pDevExt->VideoProcAmpItems[ENUM_ZOOM].Values = &pDevExt->DevPropDefine[ENUM_ZOOM].Value;
pDevExt->DevPropDefine[ENUM_BRIGHTNESS].Value = BrightnessValues;
pDevExt->DevPropDefine[ENUM_BRIGHTNESS].Value.MembersList = &pDevExt->DevPropDefine[ENUM_BRIGHTNESS].Range;
pDevExt->DevPropDefine[ENUM_BRIGHTNESS].Range = BrightnessMembersList[0];
pDevExt->DevPropDefine[ENUM_BRIGHTNESS].Default = BrightnessMembersList[1];
pDevExt->DevProperty[ENUM_BRIGHTNESS].RangeNStep = BrightnessRangeAndStep[0];
pDevExt->DevPropDefine[ENUM_SHARPNESS].Value = SharpnessValues;
pDevExt->DevPropDefine[ENUM_SHARPNESS].Value.MembersList = &pDevExt->DevPropDefine[ENUM_SHARPNESS].Range;
pDevExt->DevPropDefine[ENUM_SHARPNESS].Range = SharpnessMembersList[0];
pDevExt->DevPropDefine[ENUM_SHARPNESS].Default = SharpnessMembersList[1];
pDevExt->DevProperty[ENUM_SHARPNESS].RangeNStep = SharpnessRangeAndStep[0];
pDevExt->DevPropDefine[ENUM_HUE].Value = HueValues;
pDevExt->DevPropDefine[ENUM_HUE].Value.MembersList = &pDevExt->DevPropDefine[ENUM_HUE].Range;
pDevExt->DevPropDefine[ENUM_HUE].Range = HueMembersList[0];
pDevExt->DevPropDefine[ENUM_HUE].Default = HueMembersList[1];
pDevExt->DevProperty[ENUM_HUE].RangeNStep = HueRangeAndStep[0];
pDevExt->DevPropDefine[ENUM_SATURATION].Value = SaturationValues;
pDevExt->DevPropDefine[ENUM_SATURATION].Value.MembersList = &pDevExt->DevPropDefine[ENUM_SATURATION].Range;
pDevExt->DevPropDefine[ENUM_SATURATION].Range = SaturationMembersList[0];
pDevExt->DevPropDefine[ENUM_SATURATION].Default = SaturationMembersList[1];
pDevExt->DevProperty[ENUM_SATURATION].RangeNStep = SaturationRangeAndStep[0];
pDevExt->DevPropDefine[ENUM_WHITEBALANCE].Value = WhiteBalanceValues;
pDevExt->DevPropDefine[ENUM_WHITEBALANCE].Value.MembersList = &pDevExt->DevPropDefine[ENUM_WHITEBALANCE].Range;
pDevExt->DevPropDefine[ENUM_WHITEBALANCE].Range = WhiteBalanceMembersList[0];
pDevExt->DevPropDefine[ENUM_WHITEBALANCE].Default = WhiteBalanceMembersList[1];
pDevExt->DevProperty[ENUM_WHITEBALANCE].RangeNStep = WhiteBalanceRangeAndStep[0];
pDevExt->DevPropDefine[ENUM_FOCUS].Value = FocusValues;
pDevExt->DevPropDefine[ENUM_FOCUS].Value.MembersList = &pDevExt->DevPropDefine[ENUM_FOCUS].Range;
pDevExt->DevPropDefine[ENUM_FOCUS].Range = FocusMembersList[0];
pDevExt->DevPropDefine[ENUM_FOCUS].Default = FocusMembersList[1];
pDevExt->DevProperty[ENUM_FOCUS].RangeNStep = FocusRangeAndStep[0];
pDevExt->DevPropDefine[ENUM_ZOOM].Value = ZoomValues;
pDevExt->DevPropDefine[ENUM_ZOOM].Value.MembersList = &pDevExt->DevPropDefine[ENUM_ZOOM].Range;
pDevExt->DevPropDefine[ENUM_ZOOM].Range = ZoomMembersList[0];
pDevExt->DevPropDefine[ENUM_ZOOM].Default = ZoomMembersList[1];
pDevExt->DevProperty[ENUM_ZOOM].RangeNStep = ZoomRangeAndStep[0];
return STATUS_SUCCESS;
}
BOOL
DCamGetVideoMode(
PDCAM_EXTENSION pDevExt,
PIRB pIrb
)
/*
Query Video format and mode supported by the camera.
*/
{
NTSTATUS Status;
// First check if V_MODE_INQ (Format_0) is supported.
pDevExt->DCamVFormatInq.AsULONG = 0;
Status = DCamReadRegister(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, VFormat), &(pDevExt->DCamVFormatInq.AsULONG));
if(NT_SUCCESS(Status)) {
pDevExt->DCamVFormatInq.AsULONG = bswap(pDevExt->DCamVFormatInq.AsULONG);
if(pDevExt->DCamVFormatInq.VFormat.Format0 == 1) {
DbgMsg1(("\'V_FORMAT_INQ %x; Format:[0]:%d; [1]:%d; [2]:%d; [6]:%d; [7]:%d\n",
pDevExt->DCamVFormatInq.AsULONG,
pDevExt->DCamVFormatInq.VFormat.Format0,
pDevExt->DCamVFormatInq.VFormat.Format1,
pDevExt->DCamVFormatInq.VFormat.Format2,
pDevExt->DCamVFormatInq.VFormat.Format6,
pDevExt->DCamVFormatInq.VFormat.Format7
));
pDevExt->DCamVModeInq0.AsULONG = 0;
Status = DCamReadRegister(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, VModeInq[0]), &(pDevExt->DCamVModeInq0.AsULONG));
if(NT_SUCCESS(Status)) {
pDevExt->DCamVModeInq0.AsULONG = bswap(pDevExt->DCamVModeInq0.AsULONG);
DbgMsg1(("\'V_MODE_INQ[0] %x; Mode[]:\n [0](160x120 YUV444):%d\n [1](320x240 YUV422):%d\n [2](640x480 YUV411):%d\n [3](640x480 YUV422):%d\n [4](640x480 RGB24):%d\n [5](640x480 YMono):%d\n",
pDevExt->DCamVModeInq0.AsULONG,
pDevExt->DCamVModeInq0.VMode.Mode0,
pDevExt->DCamVModeInq0.VMode.Mode1,
pDevExt->DCamVModeInq0.VMode.Mode2,
pDevExt->DCamVModeInq0.VMode.Mode3,
pDevExt->DCamVModeInq0.VMode.Mode4,
pDevExt->DCamVModeInq0.VMode.Mode5
));
} else {
ERROR_LOG(("\'Read V_MODE_INQ_0 failed:%x!\n", Status))
}
} else {
ERROR_LOG(("\'V_MODE_INQ Format_0 not supported!\n"))
}
} else {
ERROR_LOG(("\'Read V_MODE_INQ failed:%x!\n", Status));
}
return NT_SUCCESS(Status);
}