ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

adapter.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.