mintopo.cpp

来自「ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机」· C++ 代码 · 共 1,496 行 · 第 1/4 页

CPP
1,496
字号
					} else
					if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
						if (*Level <= (VolTable[i].min << 16)) {
							mixerValue = 0;
							that->NodeCache[(2*PropertyRequest->Node)+channel] = VolTable[i].min << 16;
						} else
						if (*Level >= (VolTable[i].max << 16)) {
							mixerValue = VolTable[i].mask;
							that->NodeCache[(2*PropertyRequest->Node)+channel] = VolTable[i].max << 16;
						} else {
							mixerValue = ((*Level >> (VolTable[i].dbshift+16)) + VolTable[i].mask) & VolTable[i].mask;
							that->NodeCache[(2*PropertyRequest->Node)+channel] = *Level;
						}
						that->CMIAdapter->writeMixer(VolTable[i].reg+channel, mixerValue << VolTable[i].shift);
					}
					ntStatus = STATUS_SUCCESS;
				}
			}
			if (PropertyRequest->Node == KSNODE_TOPO_AUX_VOLUME) {
				if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
					mixerValue = that->auxVolumeRegister;
					*Level     = that->NodeCache[(2*PropertyRequest->Node)+channel];
					if (channel == CHAN_LEFT) {
						mixerValue >>= 4;
					}
					mixerValue &= 0x0F;
					if (mixerValue != ((*Level >> 18)+0x0F)) {
						*Level = (mixerValue - 0x0F) << 18;
						that->NodeCache[(2*PropertyRequest->Node)+channel] = *Level;
					}
				} else
				if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
					if (*Level <= (-30 << 16)) {
						mixerValue = 0;
						that->NodeCache[(2*PropertyRequest->Node)+channel] = -30 << 16;
					} else
					if (*Level >= 0) {
						mixerValue = 0x0F;
						that->NodeCache[(2*PropertyRequest->Node)+channel] = 0;
					} else	{
						mixerValue = ((*Level >> 18) + 0x0F) & 0x0F;
						that->NodeCache[(2*PropertyRequest->Node)+channel] = *Level;
					}

					if (channel == CHAN_RIGHT) {
						that->auxVolumeRegister = (that->auxVolumeRegister & 0xF0) | mixerValue;
					} else if (channel == CHAN_LEFT) {
						that->auxVolumeRegister = (that->auxVolumeRegister & 0x0F) | (mixerValue << 4);
					}
					that->CMIAdapter->writeUInt8(REG_MIXER3, that->auxVolumeRegister);
				}
				ntStatus = STATUS_SUCCESS;
			}
			if ((PropertyRequest->Node == KSNODE_TOPO_MICIN_VOLUME) && (channel == CHAN_LEFT)) {
				if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
					*Level     = that->NodeCache[(2*PropertyRequest->Node)];
					mixerValue = that->micVolumeRegister >> 1 & 0x7;
					if (mixerValue != ((*Level >> 19)+0x07)) {
						*Level = (mixerValue - 0x07) << 19;
						that->NodeCache[(2*PropertyRequest->Node)] = *Level;
					}
				} else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
					if (*Level <= (-56 << 16)) {
						mixerValue = 0;
						that->NodeCache[(2*PropertyRequest->Node)] = -56 << 16;
					} else if (*Level >= 0) {
						mixerValue = 0x07;
						that->NodeCache[(2*PropertyRequest->Node)] = 0;
					} else {
						mixerValue = ((*Level >> 19) + 0x07) & 0x07;
						that->NodeCache[(2*PropertyRequest->Node)] = *Level;
					}
					that->micVolumeRegister &= ~(0x07 << 1);
					that->micVolumeRegister |= mixerValue << 1;
					that->CMIAdapter->writeUInt8(REG_MIXER2, that->micVolumeRegister);
				}
				ntStatus = STATUS_SUCCESS;
			}
			if ((NT_SUCCESS(ntStatus)) && (PropertyRequest->Verb & KSPROPERTY_TYPE_GET)) {
				PropertyRequest->ValueSize = sizeof(LONG);
			}
		}
	} else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
		switch(PropertyRequest->Node) {
			case KSNODE_TOPO_LINEOUT_VOLUME:
			case KSNODE_TOPO_WAVEOUT_VOLUME:
			case KSNODE_TOPO_CD_VOLUME:
			case KSNODE_TOPO_LINEIN_VOLUME:
			case KSNODE_TOPO_MICOUT_VOLUME:
			case KSNODE_TOPO_MICIN_VOLUME:
			case KSNODE_TOPO_AUX_VOLUME:
				ntStatus = BasicSupportHandler(PropertyRequest);
				break;
		}
	}

	return ntStatus;
}

static NTSTATUS PropertyHandler_CpuResources(PPCPROPERTY_REQUEST   PropertyRequest)
{
	PAGED_CODE();
	ASSERT(PropertyRequest);
	DBGPRINT(("[PropertyHandler_CpuResources]"));

	NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;

	if (PropertyRequest->Node == (ULONG)-1) {
		return ntStatus;
	}
	if (PropertyRequest->Node >= KSNODE_TOPO_INVALID) {
		return ntStatus;
	}

	if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
		if (PropertyRequest->ValueSize >= sizeof(LONG)) {
			*((PLONG)PropertyRequest->Value) = KSAUDIO_CPU_RESOURCES_NOT_HOST_CPU;

			PropertyRequest->ValueSize = sizeof(LONG);
			ntStatus = STATUS_SUCCESS;
		} else  {
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		}
	} else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
		if (PropertyRequest->ValueSize >= (sizeof(KSPROPERTY_DESCRIPTION))) {
			PKSPROPERTY_DESCRIPTION PropDesc = PKSPROPERTY_DESCRIPTION(PropertyRequest->Value);

			PropDesc->AccessFlags       = KSPROPERTY_TYPE_BASICSUPPORT |
			                              KSPROPERTY_TYPE_GET;
			PropDesc->DescriptionSize   = sizeof(KSPROPERTY_DESCRIPTION);
			PropDesc->PropTypeSet.Set   = KSPROPTYPESETID_General;
			PropDesc->PropTypeSet.Id    = VT_I4;
			PropDesc->PropTypeSet.Flags = 0;
			PropDesc->MembersListCount  = 0;
			PropDesc->Reserved          = 0;

			PropertyRequest->ValueSize = sizeof(KSPROPERTY_DESCRIPTION);
			ntStatus = STATUS_SUCCESS;
		} else if (PropertyRequest->ValueSize >= sizeof(ULONG)) {
			PULONG AccessFlags = PULONG(PropertyRequest->Value);

			*AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET;

			PropertyRequest->ValueSize = sizeof(ULONG);
			ntStatus = STATUS_SUCCESS;
		}
	}

	return ntStatus;
}

NTSTATUS PropertyHandler_ComponentId(PPCPROPERTY_REQUEST PropertyRequest)
{
	PAGED_CODE();
	ASSERT(PropertyRequest);
	DBGPRINT(("[PropertyHandler_ComponentId]"));

	NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
	CCMITopology *that = (CCMITopology *) ((PMINIPORTTOPOLOGY) PropertyRequest->MajorTarget);

	if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
		if (PropertyRequest->ValueSize >= sizeof(KSCOMPONENTID)) {
			PKSCOMPONENTID pComponentId = (PKSCOMPONENTID)PropertyRequest->Value;

			pComponentId->Manufacturer = MANUFACTURER_CM8738;
			pComponentId->Product      = PRODUCT_CM8738;
			pComponentId->Component    = COMPONENT_CM8738;
			pComponentId->Name         = GUID_NULL;
			pComponentId->Version      = CMIPCI_VERSION;
			pComponentId->Revision     = that->cm->chipVersion;

			PropertyRequest->ValueSize = sizeof(KSCOMPONENTID);
			ntStatus = STATUS_SUCCESS;
		} else if (PropertyRequest->ValueSize == 0) {
			PropertyRequest->ValueSize = sizeof(KSCOMPONENTID);
			ntStatus = STATUS_BUFFER_OVERFLOW;
		} else {
			PropertyRequest->ValueSize = 0;
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		}
	} else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
		if (PropertyRequest->ValueSize >= sizeof(ULONG)) {
			PULONG AccessFlags = PULONG(PropertyRequest->Value);

			*AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET;

			PropertyRequest->ValueSize = sizeof(ULONG);
			ntStatus = STATUS_SUCCESS;
		} else {
			PropertyRequest->ValueSize = 0;
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		}
	}

	return ntStatus;
}

NTSTATUS PropertyHandler_Private(PPCPROPERTY_REQUEST PropertyRequest)
{
	PAGED_CODE();
	ASSERT(PropertyRequest);
	DBGPRINT(("[PropertyHandler_Private]"));

	NTSTATUS     ntStatus = STATUS_INVALID_DEVICE_REQUEST;
	CCMITopology *that = (CCMITopology *) ((PMINIPORTTOPOLOGY) PropertyRequest->MajorTarget);

	if (PropertyRequest->Verb & KSPROPERTY_TYPE_GET) {
		if (PropertyRequest->PropertyItem->Id != KSPROPERTY_CMI_GET) {
			return STATUS_INVALID_DEVICE_REQUEST;
		}

		if (PropertyRequest->ValueSize == 0) {
			PropertyRequest->ValueSize = sizeof(CMIDATA);
			return STATUS_BUFFER_OVERFLOW;
		} else if (PropertyRequest->ValueSize < sizeof (CMIDATA)) {
			PropertyRequest->ValueSize = 0;
			return STATUS_BUFFER_TOO_SMALL;
		}

		CMIDATA* cmiData = (CMIDATA*)PropertyRequest->Value;
#ifdef WAVERT
		RtlStringCbPrintfA(cmiData->driverVersion, sizeof(cmiData->driverVersion), CMIVERSION "-WaveRT");
#else
		RtlStringCbPrintfA(cmiData->driverVersion, sizeof(cmiData->driverVersion), CMIVERSION);
#endif
		cmiData->hardwareRevision    = that->cm->chipVersion;
		cmiData->maxChannels         = that->cm->maxChannels;
		cmiData->IOBase              = (USHORT)that->cm->IOBase;
		cmiData->MPUBase             = (USHORT)that->cm->MPUBase;
		cmiData->enableSPDO          = that->cm->enableSPDIFOut;
		cmiData->enableSPDI          = that->cm->enableSPDIFIn;
		cmiData->formatMask          = that->cm->formatMask;
		cmiData->exchangeFrontBack   = (that->CMIAdapter->readUInt8(REG_MIXER1) & REAR2FRONT);
		cmiData->enableSPDO5V        = (that->CMIAdapter->readUInt32(REG_MISCCTRL) & EN_SPDO5V);
		cmiData->enablePCMDAC        = (that->CMIAdapter->readUInt8(REG_MIXER1) & EN_SPDI2DAC);
		cmiData->enableBass2Line     = (that->CMIAdapter->readUInt32(REG_LEGACY) & BASS2LINE);
		cmiData->enableCenter2Line   = (that->CMIAdapter->readUInt32(REG_LEGACY) & CENTER2LINE);
		cmiData->enableRear2Line     = (that->CMIAdapter->readUInt8(REG_MIXER1) & REAR2LINE);
		cmiData->enableCenter2Mic    = (that->CMIAdapter->readUInt8(REG_MIXER4) & CENTER2MIC) && (that->cm->chipVersion > 37);
		cmiData->enableSPDOCopyright = (that->CMIAdapter->readUInt32(REG_LEGACY) & EN_SPDCOPYRHT);
		cmiData->invertValidBitSPDI  = (that->CMIAdapter->readUInt32(REG_CHFORMAT) & POLVALID);
		cmiData->loopSPDI            = (that->CMIAdapter->readUInt32(REG_FUNCTRL1) & LOOP_SPDF);
		if (that->cm->chipVersion <= 37) {
			cmiData->select2ndSPDI   = (that->CMIAdapter->readUInt32(REG_CHFORMAT) & SEL_SPDIFI1);
			cmiData->invertPhaseSPDI = (that->CMIAdapter->readUInt8(REG_MIXER4) & INV_SPDIFI1);
		} else {
			cmiData->select2ndSPDI   = (that->CMIAdapter->readUInt32(REG_MISCCTRL) & SEL_SPDIFI2);
			cmiData->invertPhaseSPDI = (that->CMIAdapter->readUInt32(REG_CHFORMAT) & INV_SPDIFI2);
		}

		PropertyRequest->ValueSize = sizeof(CMIDATA);
		ntStatus = STATUS_SUCCESS;
	} else if (PropertyRequest->Verb & KSPROPERTY_TYPE_SET) {
		if (PropertyRequest->PropertyItem->Id != KSPROPERTY_CMI_SET) {
			return STATUS_INVALID_DEVICE_REQUEST;
		}

		if (PropertyRequest->ValueSize == 0) {
			PropertyRequest->ValueSize = sizeof(CMIDATA);
			return STATUS_BUFFER_OVERFLOW;
		} else if (PropertyRequest->ValueSize < sizeof (CMIDATA)) {
			PropertyRequest->ValueSize = 0;
			return STATUS_BUFFER_TOO_SMALL;
		}
		CMIDATA* cmiData = (CMIDATA*)PropertyRequest->Value;
		that->cm->enableSPDIFIn         = cmiData->enableSPDI;
		that->cm->enableSPDIFOut        = cmiData->enableSPDO;
		that->cm->formatMask            = cmiData->formatMask;

		if (cmiData->enableSPDI) {
			that->CMIAdapter->setUInt8Bit(REG_MIXER1, EN_WAVEIN_L | EN_WAVEIN_R);
		} else {
			that->CMIAdapter->clearUInt8Bit(REG_MIXER1, EN_WAVEIN_L | EN_WAVEIN_R);
		}

		if (cmiData->exchangeFrontBack) {
			that->CMIAdapter->setUInt8Bit(REG_MIXER1, REAR2FRONT);
		} else {
			that->CMIAdapter->clearUInt8Bit(REG_MIXER1, REAR2FRONT);
		}
		if (cmiData->enableSPDO5V) {
			that->CMIAdapter->setUInt32Bit(REG_MISCCTRL, EN_SPDO5V);
		} else {
			that->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, EN_SPDO5V);
		}
		if (cmiData->enablePCMDAC) {
			that->CMIAdapter->setUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
		} else {
			that->CMIAdapter->clearUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
		}
		if (cmiData->enableBass2Line) {
			that->CMIAdapter->setUInt32Bit(REG_LEGACY, BASS2LINE);
		} else {
			that->CMIAdapter->clearUInt32Bit(REG_LEGACY, BASS2LINE);
		}
		if (cmiData->enableCenter2Line) {
			that->CMIAdapter->setUInt32Bit(REG_LEGACY, CENTER2LINE);
		} else {
			that->CMIAdapter->clearUInt32Bit(REG_LEGACY, CENTER2LINE);
		}
		if (cmiData->enableRear2Line) {
			that->CMIAdapter->setUInt8Bit(REG_MIXER1, REAR2LINE);
		} else {
			that->CMIAdapter->clearUInt8Bit(REG_MIXER1, REAR2LINE);
		}
		if (that->cm->chipVersion > 37) {
			if (cmiData->enableCenter2Mic) {
				that->CMIAdapter->setUInt8Bit(REG_MIXER4, CENTER2MIC);
			} else {
				that->CMIAdapter->clearUInt8Bit(REG_MIXER4, CENTER2MIC);
			}
		}
		if (cmiData->enableSPDOCopyright) {
			that->CMIAdapter->setUInt32Bit(REG_LEGACY, EN_SPDCOPYRHT);
		} else {
			that->CMIAdapter->clearUInt32Bit(REG_LEGACY, EN_SPDCOPYRHT);
		}
		if (cmiData->invertValidBitSPDI) {
			that->CMIAdapter->setUInt32Bit(REG_CHFORMAT, POLVALID);
		} else {
			that->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, POLVALID);
		}
		if (cmiData->loopSPDI) {
			that->CMIAdapter->setUInt32Bit(REG_FUNCTRL1, LOOP_SPDF);
		} else {
			that->CMIAdapter->clearUInt32Bit(REG_FUNCTRL1, LOOP_SPDF);
		}
		if (cmiData->select2ndSPDI) {
			if (that->cm->chipVersion <= 37) {
				that->CMIAdapter->setUInt32Bit(REG_CHFORMAT, SEL_SPDIFI1);
			} else {
				that->CMIAdapter->setUInt32Bit(REG_MISCCTRL, SEL_SPDIFI2);
			}
		} else {
			if (that->cm->chipVersion <= 37) {
				that->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, SEL_SPDIFI1);
			} else {
				that->CMIAdapter->clearUInt32Bit(REG_MISCCTRL, SEL_SPDIFI2);
			}
		}
		if (cmiData->invertPhaseSPDI) {
			if (that->cm->chipVersion <= 37) {
				that->CMIAdapter->setUInt8Bit(REG_MIXER4, INV_SPDIFI1);
			} else {
				that->CMIAdapter->setUInt32Bit(REG_CHFORMAT, INV_SPDIFI2);
			}
		} else {
			if (that->cm->chipVersion <= 37) {
				that->CMIAdapter->clearUInt8Bit(REG_MIXER4, INV_SPDIFI1);
			} else {
				that->CMIAdapter->clearUInt32Bit(REG_CHFORMAT, INV_SPDIFI2);
			}
		}

		that->storeMixerSettingsToRegistry();

		ntStatus = STATUS_SUCCESS;
	} else if (PropertyRequest->Verb & KSPROPERTY_TYPE_BASICSUPPORT) {
		if (PropertyRequest->ValueSize >= sizeof(ULONG)) {
			PULONG AccessFlags = PULONG(PropertyRequest->Value);

			*AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET;

			PropertyRequest->ValueSize = sizeof(ULONG);
			ntStatus = STATUS_SUCCESS;
		} else {
			PropertyRequest->ValueSize = 0;
			ntStatus = STATUS_BUFFER_TOO_SMALL;
		}
	}

	return ntStatus;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?