Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenadapter.cpp
Go to the documentation of this file.
00001 /* 00002 Copyright (c) 2006-2007 dogbert <dogber1@gmail.com> 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without 00006 modification, are permitted provided that the following conditions 00007 are met: 00008 1. Redistributions of source code must retain the above copyright 00009 notice, this list of conditions and the following disclaimer. 00010 2. Redistributions in binary form must reproduce the above copyright 00011 notice, this list of conditions and the following disclaimer in the 00012 documentation and/or other materials provided with the distribution. 00013 3. The name of the author may not be used to endorse or promote products 00014 derived from this software without specific prior written permission. 00015 00016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 00020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 */ 00027 00028 #define PUT_GUIDS_HERE 00029 #include <initguid.h> 00030 #include "adapter.hpp" 00031 00032 #ifdef _MSC_VER 00033 //#pragma code_seg("PAGE") // GCC ignores pragma code_seg 00034 #endif 00035 00036 const GUID KSNODETYPE_DAC = {0x507AE360L, 0xC554, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00037 const GUID KSNODETYPE_ADC = {0x4D837FE0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00038 const GUID KSNODETYPE_AGC = {0xE88C9BA0L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00039 const GUID KSNODETYPE_LOUDNESS = {0x41887440L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00040 const GUID KSNODETYPE_MUTE = {0x02B223C0L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00041 const GUID KSNODETYPE_TONE = {0x7607E580L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00042 const GUID KSNODETYPE_VOLUME = {0x3A5ACC00L, 0xC557, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00043 const GUID KSNODETYPE_PEAKMETER = {0xa085651e, 0x5f0d, 0x4b36, {0xa8, 0x69, 0xd1, 0x95, 0xd6, 0xab, 0x4b, 0x9e}}; 00044 const GUID KSNODETYPE_MUX = {0x2CEAF780, 0xC556, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00045 const GUID KSNODETYPE_STEREO_WIDE = {0xA9E69800L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00046 const GUID KSNODETYPE_CHORUS = {0x20173F20L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00047 const GUID KSNODETYPE_REVERB = {0xEF0328E0L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00048 const GUID KSNODETYPE_SUPERMIX = {0xE573ADC0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00049 const GUID KSNODETYPE_SUM = {0xDA441A60L, 0xC556, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00050 const GUID KSNODETYPE_SRC = {0x9DB7B9E0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00051 const GUID KSNODETYPE_3D_EFFECTS = {0x55515860L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; 00052 const GUID KSNODETYPE_SPDIF_INTERFACE = {0x0605+0xDFF219E0, 0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 00053 const GUID KSNODETYPE_MICROPHONE = {0x0201+0xDFF219E0,0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 00054 const GUID KSNODETYPE_CD_PLAYER = {0x0703+0xDFF219E0,0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 00055 const GUID KSNODETYPE_LINE_CONNECTOR = {0x0603+0xDFF219E0,0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 00056 const GUID KSNODETYPE_ANALOG_CONNECTOR = {0x601+0xDFF219E0,0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 00057 const GUID KSNODETYPE_SPEAKER = {0x0301+0xDFF219E0,0xF70F, 0x11D0, {0xB9, 0x17, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 00058 00059 const GUID KSPROPTYPESETID_General = {0x97E99BA0L, 0xBDEA, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00060 const GUID KSPROPSETID_General = {0x1464EDA5L, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 00061 const GUID KSPROPSETID_Audio = {0x45FFAAA0L, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; 00062 const GUID GUID_NULL ={0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; 00063 const GUID KSCATEGORY_AUDIO = {0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; 00064 00065 00066 const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; 00067 const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; 00068 const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; 00069 const GUID KSDATAFORMAT_SPECIFIER_DSOUND = {0x518590a2L, 0xa184, 0x11d0, {0x85, 0x22, 0x00, 0xc0, 0x4f, 0xd9, 0xba, 0xf3}}; 00070 const GUID KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = {0x00000000L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; 00071 const GUID KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF = {0x00000092L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; 00072 00073 00074 const GUID KSAUDFNAME_WAVE_VOLUME = {0x185FEDE5L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00075 const GUID KSAUDFNAME_WAVE_MUTE = {0x185FEDE6L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00076 const GUID KSAUDFNAME_MIC_VOLUME = {0x185FEDEDL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00077 const GUID KSAUDFNAME_MASTER_VOLUME = {0x185FEDE3L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00078 const GUID KSAUDFNAME_RECORDING_SOURCE = {0x185FEDEFL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00079 const GUID KSAUDFNAME_CD_VOLUME = {0x185FEDE9L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00080 const GUID KSAUDFNAME_CD_IN_VOLUME = {0x185FEDF3L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00081 const GUID KSAUDFNAME_MIC_IN_VOLUME = {0x185FEDF5L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00082 const GUID KSAUDFNAME_MICROPHONE_BOOST = {0x2bc31d6aL, 0x96e3, 0x11d2, {0xac, 0x4c, 0x0, 0xc0, 0x4f, 0x8e, 0xfb, 0x68}}; 00083 const GUID KSAUDFNAME_CD_MUTE = {0x185FEDEAL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00084 const GUID KSAUDFNAME_LINE_MUTE = {0x185FEDECL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00085 const GUID KSAUDFNAME_MIC_MUTE = {0x185FEDEEL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00086 const GUID KSAUDFNAME_AUX_MUTE = {0x185FEDFDL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00087 const GUID KSAUDFNAME_MASTER_MUTE = {0x185FEDE4L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00088 const GUID KSAUDFNAME_RECORDING_CONTROL = {0x185FEDFAL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00089 const GUID KSAUDFNAME_VOLUME_CONTROL = {0x185FEDF7L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00090 const GUID KSAUDFNAME_LINE_IN_VOLUME = {0x185FEDF4L, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00091 const GUID KSAUDFNAME_AUX_VOLUME = {0x185FEDFCL, 0x9905, 0x11D1, {0x95, 0xA9, 0x00, 0xC0, 0x4F, 0xB9, 0x25, 0xD3}}; 00092 00093 const GUID KSPROPSETID_CMI = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFF}}; 00094 00095 00096 const GUID CMINAME_IEC_5V = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF0}}; 00097 const GUID CMINAME_IEC_OUT = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF1}}; 00098 const GUID CMINAME_IEC_INVERSE = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF2}}; 00099 const GUID CMINAME_IEC_MONITOR = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF3}}; 00100 const GUID CMINAME_IEC_SELECT = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF5}}; 00101 const GUID CMINAME_XCHG_FB = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF6}}; 00102 const GUID CMINAME_BASS2LINE = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF7}}; 00103 const GUID CMINAME_CENTER2LINE = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF8}}; 00104 const GUID CMINAME_IEC_COPYRIGHT = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF9}}; 00105 const GUID CMINAME_IEC_POLVALID = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFA}}; 00106 const GUID CMINAME_IEC_LOOP = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFB}}; 00107 const GUID CMINAME_REAR2LINE = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFC}}; 00108 const GUID CMINAME_CENTER2MIC = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xFD}}; 00109 const GUID CMINAME_DAC = {0x2B81CDBB, 0xEE6C, 0x4ECC, {0x8A, 0xA5, 0x9A, 0x18, 0x8B, 0x02, 0x3D, 0xF4}}; 00110 const GUID PRODUCT_CM8738 = {0x9db14e9a, 0x7be7, 0x480d, {0xa2, 0xfa, 0x32, 0x93, 0x24, 0x89, 0xde, 0x9c}}; 00111 const GUID COMPONENT_CM8738 = {0x9db14e9a, 0x7be7, 0x480d, {0xa2, 0xfa, 0x32, 0x93, 0x24, 0x89, 0xde, 0x9d}}; 00112 const GUID MANUFACTURER_CM8738 = {0x9db14e9a, 0x7be7, 0x480d, {0xa2, 0xfa, 0x32, 0x93, 0x24, 0x89, 0xde, 0x9e}}; 00113 00114 00115 NTSTATUS InstallSubdevice( 00116 PDEVICE_OBJECT DeviceObject, 00117 PIRP Irp, 00118 PWCHAR Name, 00119 REFGUID PortClassId, 00120 REFGUID MiniportClassId, 00121 PFNCREATEINSTANCE MiniportCreate, 00122 PUNKNOWN UnknownAdapter, 00123 PRESOURCELIST ResourceList, 00124 REFGUID PortInterfaceId, 00125 PUNKNOWN* OutPortUnknown) 00126 { 00127 NTSTATUS ntStatus; 00128 PPORT Port; 00129 PMINIPORT MiniPort; 00130 00132 DBGPRINT(("InstallSubdevice()")); 00133 00134 ntStatus = PcNewPort(&Port, PortClassId); 00135 if (NT_SUCCESS(ntStatus)) { 00136 if (MiniportCreate) { 00137 ntStatus = MiniportCreate((PUNKNOWN*)&MiniPort, MiniportClassId, NULL, NonPagedPool); 00138 } else { 00139 ntStatus = PcNewMiniport(&MiniPort, MiniportClassId); 00140 } 00141 } 00142 00143 if (!NT_SUCCESS(ntStatus)) { 00144 Port->Release(); 00145 return ntStatus; 00146 } 00147 00148 ntStatus = Port->Init(DeviceObject, Irp, MiniPort, UnknownAdapter, ResourceList); 00149 if (NT_SUCCESS(ntStatus)) { 00150 ntStatus = PcRegisterSubdevice(DeviceObject, Name, Port); 00151 00152 if (OutPortUnknown && NT_SUCCESS (ntStatus)) { 00153 ntStatus = Port->QueryInterface(IID_IUnknown, (PVOID *)OutPortUnknown); 00154 } 00155 } 00156 00157 if (MiniPort) { 00158 MiniPort->Release(); 00159 } 00160 00161 if (Port) { 00162 Port->Release(); 00163 } 00164 00165 return ntStatus; 00166 } 00167 00168 00169 NTSTATUS 00170 ProcessResources( 00171 PRESOURCELIST ResourceList, 00172 PRESOURCELIST* UartResourceList) 00173 { 00174 NTSTATUS ntStatus; 00175 00179 //DBGPRINT(("ProcessResources()")); 00180 //DBGPRINT(("NumberOfPorts: %d, NumberOfInterrupts: %d, NumberOfDmas: %d", ResourceList->NumberOfPorts(), ResourceList->NumberOfInterrupts(), ResourceList->NumberOfDmas())); 00181 00182 #ifdef UART 00183 (*UartResourceList) = NULL; 00184 #endif 00185 00186 00187 if ((ResourceList->NumberOfPorts() == 0) || (ResourceList->NumberOfPorts() > 2) || (ResourceList->NumberOfInterrupts() != 1) || (ResourceList->NumberOfDmas() != 0)) { 00188 DBGPRINT(("Unexpected configuration")); 00189 return STATUS_DEVICE_CONFIGURATION_ERROR; 00190 } 00191 00192 #ifdef UART 00193 ntStatus = PcNewResourceSublist(UartResourceList, NULL, PagedPool, ResourceList, 2); 00194 if (NT_SUCCESS(ntStatus)) { 00195 (*UartResourceList)->AddPortFromParent(ResourceList, 1); 00196 (*UartResourceList)->AddInterruptFromParent(ResourceList, 0); 00197 } 00198 #endif 00199 00200 return STATUS_SUCCESS; 00201 } 00202 00203 00204 NTSTATUS StartDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp, PRESOURCELIST ResourceList) 00205 { 00206 NTSTATUS ntStatus; 00207 PPORT pPort = 0; 00208 ULONG* MPUBase; 00209 #if 0 00210 //PAGED_CODE(); 00211 //ASSERT(DeviceObject); 00212 //ASSERT(Irp); 00213 //ASSERT(ResourceList); 00214 DBGPRINT(("StartDevice()")); 00215 #endif 00216 00217 ntStatus = PcNewPort(&pPort,CLSID_PortWaveCyclic); 00218 if (NT_SUCCESS(ntStatus)) { 00219 // not supported in the first edition of win98 00220 PPORTEVENTS pPortEvents = 0; 00221 ntStatus = pPort->QueryInterface(IID_IPortEvents, (PVOID *)&pPortEvents); 00222 if (!NT_SUCCESS(ntStatus)) { 00223 DBGPRINT(("ERROR: This driver doesn't work under Win98!")); 00224 ntStatus = STATUS_UNSUCCESSFUL; 00225 } 00226 else 00227 { 00228 pPortEvents->Release(); 00229 } 00230 pPort->Release (); 00231 } else { 00232 return ntStatus; 00233 } 00234 00235 // resource validation 00236 PRESOURCELIST UartResourceList = NULL; 00237 ntStatus = ProcessResources(ResourceList, &UartResourceList); 00238 if (!NT_SUCCESS(ntStatus)) { 00239 DBGPRINT(("ProcessResources() failed")); 00240 return ntStatus; 00241 } 00242 00243 PCMIADAPTER pCMIAdapter = NULL; 00244 PUNKNOWN pUnknownCommon = NULL; 00245 00246 // create the CMIAdapter object 00247 ntStatus = NewCMIAdapter(&pUnknownCommon, IID_ICMIAdapter, NULL, NonPagedPool); 00248 if (!NT_SUCCESS(ntStatus)) { 00249 DBGPRINT(("NewCMIAdapter() failed")); 00250 return ntStatus; 00251 } 00252 00253 ntStatus = pUnknownCommon->QueryInterface(IID_ICMIAdapter, (PVOID *)&pCMIAdapter); 00254 if (!NT_SUCCESS(ntStatus)) { 00255 DBGPRINT(("QueryInterface() for ICMIAdapter failed")); 00256 return ntStatus; 00257 } 00258 ntStatus = pCMIAdapter->init(ResourceList, DeviceObject); 00259 if (!NT_SUCCESS(ntStatus)) { 00260 DBGPRINT(("CMIAdapter->init() failed")); 00261 return ntStatus; 00262 } 00263 00264 ntStatus = PcRegisterAdapterPowerManagement((PUNKNOWN)pCMIAdapter, DeviceObject); 00265 00266 pUnknownCommon->Release(); 00267 00268 PUNKNOWN unknownWave = NULL; 00269 PUNKNOWN unknownTopology = NULL; 00270 00271 // install the topology miniport. 00272 ntStatus = InstallSubdevice( DeviceObject, Irp, (PWCHAR) L"Topology", 00273 CLSID_PortTopology, CLSID_PortTopology, CreateMiniportTopologyCMI, 00274 pCMIAdapter, NULL, GUID_NULL, &unknownTopology ); 00275 if (!NT_SUCCESS (ntStatus)) { 00276 DBGPRINT(("Topology miniport installation failed")); 00277 return ntStatus; 00278 } 00279 00280 #ifdef UART 00281 // install the UART miniport - execution order important 00282 ntStatus = STATUS_UNSUCCESSFUL; 00283 MPUBase = 0; 00284 for ( UINT i=0; i < ResourceList->NumberOfPorts(); i++ ) { 00285 if (ResourceList->FindTranslatedPort(i)->u.Port.Length == 2) { 00286 MPUBase = (UInt32*)ResourceList->FindTranslatedPort(i)->u.Port.Start.QuadPart; 00287 } 00288 } 00289 if (MPUBase != 0) { 00290 ntStatus = pCMIAdapter->activateMPU(MPUBase); 00291 if (NT_SUCCESS(ntStatus)) { 00292 ntStatus = InstallSubdevice( DeviceObject, Irp, (PWCHAR) L"Uart", 00293 CLSID_PortDMus, CLSID_MiniportDriverDMusUART, NULL, 00294 pCMIAdapter->getInterruptSync(), UartResourceList, 00295 IID_IPortDMus, NULL ); 00296 } 00297 } 00298 if (!NT_SUCCESS(ntStatus)) { 00299 MPUBase = 0; 00300 pCMIAdapter->activateMPU(0); 00301 DBGPRINT(("UART miniport installation failed")); 00302 } 00303 if (UartResourceList) { 00304 UartResourceList->Release(); 00305 } 00306 #endif 00307 00308 // install the wave miniport - the order matters here 00309 #ifdef WAVERT 00310 ntStatus = InstallSubdevice(DeviceObject, Irp, (PWCHAR) L"Wave", 00311 CLSID_PortWaveRT, CLSID_PortWaveRT, CreateMiniportWaveCMI, 00312 pCMIAdapter, ResourceList, IID_IPortWaveRT, &unknownWave ); 00313 #else 00314 ntStatus = InstallSubdevice(DeviceObject, Irp, (PWCHAR) L"Wave", 00315 CLSID_PortWaveCyclic, CLSID_PortWaveCyclic, CreateMiniportWaveCMI, 00316 pCMIAdapter, ResourceList, IID_IPortWaveCyclic, &unknownWave ); 00317 #endif 00318 if (!NT_SUCCESS(ntStatus)) { 00319 DBGPRINT(("Wave miniport installation failed")); 00320 return ntStatus; 00321 } 00322 00323 // connect wave and topology pins 00324 ntStatus = PcRegisterPhysicalConnection(DeviceObject, unknownWave, PIN_WAVE_RENDER_SOURCE, unknownTopology, PIN_WAVEOUT_SOURCE); 00325 if (!NT_SUCCESS(ntStatus)) { 00326 DBGPRINT(("Cannot connect topology and wave miniport (render)!")); 00327 return ntStatus; 00328 } 00329 ntStatus = PcRegisterPhysicalConnection(DeviceObject, unknownTopology, PIN_WAVEIN_DEST, unknownWave, PIN_WAVE_CAPTURE_SOURCE); 00330 if (!NT_SUCCESS(ntStatus)) { 00331 DBGPRINT(("Cannot connect topology and wave miniport (capture)!")); 00332 return ntStatus; 00333 } 00334 if (!IoIsWdmVersionAvailable(6,0)) { 00335 // this shit fixes the fucking XP mixer and breaks the vista mixer, so we have to check for vista here 00336 ntStatus = PcRegisterPhysicalConnection(DeviceObject, unknownWave, PIN_WAVE_AC3_RENDER_SOURCE, unknownTopology, PIN_SPDIF_AC3_SOURCE); 00337 if (!NT_SUCCESS(ntStatus)) { 00338 DBGPRINT(("Cannot connect topology and wave miniport (ac3)!")); 00339 } 00340 } 00341 00342 // clean up 00343 if (pCMIAdapter) { 00344 pCMIAdapter->Release(); 00345 } 00346 if (unknownTopology) { 00347 unknownTopology->Release(); 00348 } 00349 if (unknownWave) { 00350 unknownWave->Release(); 00351 } 00352 00353 return ntStatus; 00354 } 00355 00356 extern 00357 "C" 00358 NTSTATUS 00359 NTAPI 00360 AddDevice( 00361 PDRIVER_OBJECT DriverObject, 00362 PDEVICE_OBJECT PhysicalDeviceObject) 00363 { 00364 #if 0 00365 //PAGED_CODE(); 00366 DBGPRINT(("AddDevice()")); 00367 #endif 00368 00369 return PcAddAdapterDevice(DriverObject, PhysicalDeviceObject, (PCPFNSTARTDEVICE)StartDevice, MAX_MINIPORTS, 0); 00370 } 00371 00372 bool CopyResourceDescriptor(PIO_RESOURCE_DESCRIPTOR pInResDescriptor, PIO_RESOURCE_DESCRIPTOR pOutResDescriptor) 00373 { 00374 #if 0 00375 //PAGED_CODE(); 00376 //ASSERT(pInResDescriptor); 00377 //ASSERT(pOutResDescriptor); 00378 DBGPRINT(("CopyResourceDescriptor()")); 00379 RtlCopyMemory(pOutResDescriptor, pInResDescriptor, sizeof(IO_RESOURCE_DESCRIPTOR)); 00380 #else 00381 pOutResDescriptor->Type = pInResDescriptor->Type; 00382 pOutResDescriptor->ShareDisposition = pInResDescriptor->ShareDisposition; 00383 pOutResDescriptor->Flags = pInResDescriptor->Flags; 00384 pOutResDescriptor->Option = pInResDescriptor->Option; 00385 00386 switch (pInResDescriptor->Type) { 00387 case CmResourceTypePort: 00388 case CmResourceTypePort | CmResourceTypeNonArbitrated: // huh? 00389 /* // filter crap 00390 if ((pInResDescriptor->u.Port.Length == 0) || 00391 ( (pInResDescriptor->u.Port.MinimumAddress.HighPart == pInResDescriptor->u.Port.MaximumAddress.HighPart) && (pInResDescriptor->u.Port.MinimumAddress.LowPart == pInResDescriptor->u.Port.MaximumAddress.LowPart) ) ) { 00392 return FALSE; 00393 } 00394 */ pOutResDescriptor->u.Port.MinimumAddress = pInResDescriptor->u.Port.MinimumAddress; 00395 pOutResDescriptor->u.Port.MaximumAddress = pInResDescriptor->u.Port.MaximumAddress; 00396 pOutResDescriptor->u.Port.Length = pInResDescriptor->u.Port.Length; 00397 pOutResDescriptor->u.Port.Alignment = pInResDescriptor->u.Port.Alignment; 00398 #if 0 00399 DBGPRINT((" Port: min %08x.%08x max %08x.%08x, Length: %x, Option: %x", pOutResDescriptor->u.Port.MinimumAddress.HighPart, pOutResDescriptor->u.Port.MinimumAddress.LowPart, 00400 pOutResDescriptor->u.Port.MaximumAddress.HighPart, pOutResDescriptor->u.Port.MaximumAddress.LowPart, 00401 pOutResDescriptor->u.Port.Length, pOutResDescriptor->Option)); 00402 #endif 00403 break; 00404 case CmResourceTypeInterrupt: 00405 pOutResDescriptor->u.Interrupt.MinimumVector = pInResDescriptor->u.Interrupt.MinimumVector; 00406 pOutResDescriptor->u.Interrupt.MaximumVector = pInResDescriptor->u.Interrupt.MaximumVector; 00407 #if 0 00408 DBGPRINT((" IRQ: min %x max %x, Option: %d", pOutResDescriptor->u.Interrupt.MinimumVector, pOutResDescriptor->u.Interrupt.MaximumVector, pOutResDescriptor->Option)); 00409 #endif 00410 break; 00411 default: 00412 return FALSE; 00413 } 00414 return TRUE; 00415 #endif 00416 } 00417 00418 extern 00419 "C" 00420 NTSTATUS 00421 NTAPI 00422 AdapterDispatchPnp( 00423 PDEVICE_OBJECT pDeviceObject, 00424 PIRP pIrp) 00425 { 00426 NTSTATUS ntStatus = STATUS_SUCCESS; 00427 ULONG resourceListSize; 00428 PIO_RESOURCE_REQUIREMENTS_LIST resourceList, list; 00429 PIO_RESOURCE_DESCRIPTOR descriptor; 00430 PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); 00431 00435 DBGPRINT(("AdapterDispatchPnp()")); 00436 00437 if (pIrpStack->MinorFunction == IRP_MN_FILTER_RESOURCE_REQUIREMENTS) { 00438 DBGPRINT(("[AdapterDispatchPnp] - IRP_MN_FILTER_RESOURCE_REQUIREMENTS")); 00439 00440 list = (PIO_RESOURCE_REQUIREMENTS_LIST)pIrp->IoStatus.Information; 00441 00442 // IO_RESOURCE_REQUIREMENTS_LIST has 1 IO_RESOURCE_LIST, IO_RESOURCE_LIST has 1 IO_RESOURCE_DESCRIPTOR and we want 2 more 00443 resourceListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST) + sizeof(IO_RESOURCE_DESCRIPTOR)*(list->List[0].Count+2) ; 00444 resourceList = (PIO_RESOURCE_REQUIREMENTS_LIST)ExAllocatePoolWithTag(PagedPool, resourceListSize, 'LRDV'); 00445 00446 if (!resourceList) { 00447 ntStatus = STATUS_INSUFFICIENT_RESOURCES; 00448 return ntStatus; 00449 } 00450 00451 00452 RtlZeroMemory(resourceList, resourceListSize); 00453 00454 // initialize the list header 00455 resourceList->AlternativeLists = 1; // number of IO_RESOURCE_LISTs 00456 resourceList->ListSize = resourceListSize; 00457 00458 resourceList->List[0].Version = 1; 00459 resourceList->List[0].Revision = 1; 00460 resourceList->List[0].Count = 0; 00461 00462 // copy the resources which have already been assigned 00463 for ( UINT i=0; i < list->List[0].Count; i++ ) { 00464 if (CopyResourceDescriptor( &list->List[0].Descriptors[i], 00465 &resourceList->List[0].Descriptors[resourceList->List[0].Count] )) 00466 { 00467 resourceList->List[0].Count++; 00468 } 00469 } 00470 ExFreePool(list); 00471 00472 // an additional port for mpu401 00473 resourceList->List[0].Count++; 00474 descriptor = &resourceList->List[0].Descriptors[resourceList->List[0].Count-1]; 00475 descriptor->Option = IO_RESOURCE_PREFERRED; 00476 descriptor->Type = CmResourceTypePort; 00477 descriptor->ShareDisposition = CmResourceShareDeviceExclusive; 00478 descriptor->Flags = CM_RESOURCE_PORT_IO; 00479 descriptor->u.Port.MinimumAddress.LowPart = 0x300; 00480 descriptor->u.Port.MinimumAddress.HighPart = 0; 00481 descriptor->u.Port.MaximumAddress.LowPart = 0x330; 00482 descriptor->u.Port.MaximumAddress.HighPart = 0; 00483 descriptor->u.Port.Length = 2; 00484 descriptor->u.Port.Alignment = 0x10; 00485 00486 // mpu401 port should be optional. yes, this is severely braindamaged. 00487 resourceList->List[0].Count++; 00488 descriptor = &resourceList->List[0].Descriptors[resourceList->List[0].Count-1]; 00489 descriptor->Option = IO_RESOURCE_ALTERNATIVE; 00490 descriptor->Type = CmResourceTypePort; 00491 descriptor->ShareDisposition = CmResourceShareDeviceExclusive; 00492 descriptor->Flags = CM_RESOURCE_PORT_IO; 00493 descriptor->u.Port.MinimumAddress.LowPart = 0x0; 00494 descriptor->u.Port.MinimumAddress.HighPart = 0; 00495 descriptor->u.Port.MaximumAddress.LowPart = 0xFFFF; 00496 descriptor->u.Port.MaximumAddress.HighPart = 0; 00497 descriptor->u.Port.Length = 1; 00498 descriptor->u.Port.Alignment = 0x10; 00499 00500 // DBGPRINT(("number of resource list descriptors: %d", resourceList->List[0].Count)); 00501 00502 pIrp->IoStatus.Information = (ULONG_PTR)resourceList; 00503 00504 // set the return status 00505 pIrp->IoStatus.Status = ntStatus; 00506 } 00507 00508 // Pass the IRPs on to PortCls 00509 ntStatus = PcDispatchIrp(pDeviceObject, pIrp); 00510 00511 return ntStatus; 00512 } 00513 00514 extern 00515 "C" 00516 NTSTATUS 00517 NTAPI 00518 DriverEntry( 00519 PDRIVER_OBJECT DriverObject, 00520 PUNICODE_STRING RegistryPathName) 00521 { 00522 NTSTATUS ntStatus; 00523 00524 DBGPRINT(("DriverEntry()")); 00525 00526 00527 //bind the adapter driver to the portclass driver 00528 ntStatus = PcInitializeAdapterDriver(DriverObject, RegistryPathName, AddDevice); 00529 00530 00531 #ifdef UART 00532 if(NT_SUCCESS(ntStatus)) { 00533 DriverObject->MajorFunction[IRP_MJ_PNP] = AdapterDispatchPnp; 00534 } 00535 #endif 00536 #ifdef WAVERT 00537 if (!IoIsWdmVersionAvailable(6,0)) { 00538 ntStatus = STATUS_UNSUCCESSFUL; 00539 } 00540 #endif 00541 00542 return ntStatus; 00543 } 00544 00545 00546 #ifdef _MSC_VER 00547 00548 #pragma code_seg() 00549 int __cdecl _purecall (void) 00550 { 00551 return 0; 00552 } 00553 00554 #else 00555 00556 extern "C" { 00557 void __cxa_pure_virtual() 00558 { 00559 // put error handling here 00560 00561 DbgBreakPoint(); 00562 00563 } 00564 } 00565 #endif Generated on Sat May 26 2012 04:27:06 for ReactOS by
1.7.6.1
|