Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendeviface.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: drivers/wdm/audio/legacy/wdmaud/deviface.c 00005 * PURPOSE: System Audio graph builder 00006 * PROGRAMMER: Andrew Greenwood 00007 * Johannes Anderwald 00008 */ 00009 #include "wdmaud.h" 00010 00011 NTSTATUS 00012 WdmAudOpenSysAudioDevice( 00013 IN LPWSTR DeviceName, 00014 OUT PHANDLE Handle) 00015 { 00016 UNICODE_STRING SymbolicLink; 00017 OBJECT_ATTRIBUTES ObjectAttributes; 00018 IO_STATUS_BLOCK IoStatusBlock; 00019 NTSTATUS Status; 00020 00021 RtlInitUnicodeString(&SymbolicLink, DeviceName); 00022 InitializeObjectAttributes(&ObjectAttributes, &SymbolicLink, OBJ_OPENIF | OBJ_KERNEL_HANDLE, NULL, NULL); 00023 00024 Status = IoCreateFile(Handle, 00025 SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE, 00026 &ObjectAttributes, 00027 &IoStatusBlock, 00028 NULL, 00029 0, 00030 0, 00031 FILE_OPEN, 00032 FILE_SYNCHRONOUS_IO_NONALERT, 00033 NULL, 00034 0, 00035 CreateFileTypeNone, 00036 NULL, 00037 IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK); 00038 00039 return Status; 00040 } 00041 00042 NTSTATUS 00043 NTAPI 00044 DeviceInterfaceChangeCallback( 00045 IN PVOID NotificationStructure, 00046 IN PVOID Context) 00047 { 00048 DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure; 00049 00050 DPRINT1("DeviceInterfaceChangeCallback called %p\n", Event); 00051 DbgBreakPoint(); 00052 return STATUS_SUCCESS; 00053 } 00054 00055 NTSTATUS 00056 WdmAudOpenSysAudioDeviceInterfaces( 00057 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension, 00058 IN LPWSTR SymbolicLinkList) 00059 { 00060 SYSAUDIO_ENTRY * Entry; 00061 ULONG Length; 00062 00063 DPRINT1("WdmAudOpenSysAudioDeviceInterfaces called\n"); 00064 00065 while(*SymbolicLinkList) 00066 { 00067 Length = wcslen(SymbolicLinkList) + 1; 00068 Entry = (SYSAUDIO_ENTRY*)AllocateItem(NonPagedPool, sizeof(SYSAUDIO_ENTRY) + Length * sizeof(WCHAR)); 00069 if (!Entry) 00070 { 00071 return STATUS_INSUFFICIENT_RESOURCES; 00072 } 00073 00074 Entry->SymbolicLink.Length = Length * sizeof(WCHAR); 00075 Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR); 00076 Entry->SymbolicLink.Buffer = (LPWSTR) (Entry + 1); 00077 wcscpy(Entry->SymbolicLink.Buffer, SymbolicLinkList); 00078 00079 InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry); 00080 00081 DeviceExtension->NumSysAudioDevices++; 00082 SymbolicLinkList += Length; 00083 } 00084 return STATUS_SUCCESS; 00085 } 00086 00087 00088 NTSTATUS 00089 WdmAudOpenSysAudioDevices( 00090 IN PDEVICE_OBJECT DeviceObject, 00091 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension) 00092 { 00093 NTSTATUS Status = STATUS_SUCCESS; 00094 LPWSTR SymbolicLinkList; 00095 SYSAUDIO_ENTRY * Entry; 00096 ULONG Length; 00097 HANDLE hSysAudio; 00098 PFILE_OBJECT FileObject; 00099 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio\\GLOBAL"); 00100 00101 if (DeviceExtension->DeviceInterfaceSupport) 00102 { 00103 Status = IoGetDeviceInterfaces(&KSCATEGORY_SYSAUDIO, 00104 NULL, 00105 0, 00106 &SymbolicLinkList); 00107 00108 if (NT_SUCCESS(Status)) 00109 { 00110 WdmAudOpenSysAudioDeviceInterfaces(DeviceExtension, SymbolicLinkList); 00111 FreeItem(SymbolicLinkList); 00112 } 00113 00114 00115 Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, 00116 PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, 00117 (PVOID)&KSCATEGORY_SYSAUDIO, 00118 DeviceObject->DriverObject, 00119 DeviceInterfaceChangeCallback, 00120 (PVOID)DeviceExtension, 00121 &DeviceExtension->SysAudioNotification); 00122 } 00123 else 00124 { 00125 Entry = (SYSAUDIO_ENTRY*)AllocateItem(NonPagedPool, sizeof(SYSAUDIO_ENTRY)); 00126 if (!Entry) 00127 { 00128 return STATUS_INSUFFICIENT_RESOURCES; 00129 } 00130 00131 00132 Length = wcslen(DeviceName.Buffer) + 1; 00133 Entry->SymbolicLink.Length = 0; 00134 Entry->SymbolicLink.MaximumLength = Length * sizeof(WCHAR); 00135 Entry->SymbolicLink.Buffer = AllocateItem(NonPagedPool, Entry->SymbolicLink.MaximumLength); 00136 00137 if (!Entry->SymbolicLink.Buffer) 00138 { 00139 FreeItem(Entry); 00140 return STATUS_INSUFFICIENT_RESOURCES; 00141 } 00142 00143 Status = RtlAppendUnicodeStringToString(&Entry->SymbolicLink, &DeviceName); 00144 00145 if (!NT_SUCCESS(Status)) 00146 { 00147 FreeItem(Entry->SymbolicLink.Buffer); 00148 FreeItem(Entry); 00149 return Status; 00150 } 00151 00152 InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry); 00153 DeviceExtension->NumSysAudioDevices++; 00154 00155 DPRINT("Opening device %S\n", Entry->SymbolicLink.Buffer); 00156 Status = WdmAudOpenSysAudioDevice(Entry->SymbolicLink.Buffer, &hSysAudio); 00157 if (!NT_SUCCESS(Status)) 00158 { 00159 DPRINT1("Failed to open sysaudio %x\n", Status); 00160 return Status; 00161 } 00162 00163 /* get the file object */ 00164 Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); 00165 if (!NT_SUCCESS(Status)) 00166 { 00167 DPRINT1("Failed to reference FileObject %x\n", Status); 00168 ZwClose(hSysAudio); 00169 return Status; 00170 } 00171 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 00172 DeviceExtension->hSysAudio = hSysAudio; 00173 DeviceExtension->FileObject = FileObject; 00174 } 00175 00176 return Status; 00177 } 00178 00179 NTSTATUS 00180 WdmAudRegisterDeviceInterface( 00181 IN PDEVICE_OBJECT PhysicalDeviceObject, 00182 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension) 00183 { 00184 NTSTATUS Status; 00185 UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud"); 00186 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud"); 00187 UNICODE_STRING SymbolicLinkName; 00188 00189 Status = IoRegisterDeviceInterface(PhysicalDeviceObject, &KSCATEGORY_WDMAUD, NULL, &SymbolicLinkName); 00190 if (NT_SUCCESS(Status)) 00191 { 00192 IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE); 00193 RtlFreeUnicodeString(&SymbolicLinkName); 00194 DeviceExtension->DeviceInterfaceSupport = TRUE; 00195 return Status; 00196 } 00197 00198 /* failed to register device interface 00199 * create a symbolic link instead 00200 */ 00201 DeviceExtension->DeviceInterfaceSupport = FALSE; 00202 00203 Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName); 00204 if (!NT_SUCCESS(Status)) 00205 { 00206 IoDeleteDevice(PhysicalDeviceObject); //FIXME 00207 DPRINT("Failed to create wdmaud symlink!\n"); 00208 return Status; 00209 } 00210 00211 return Status; 00212 } 00213 00214 NTSTATUS 00215 WdmAudOpenSysaudio( 00216 IN PDEVICE_OBJECT DeviceObject, 00217 IN PWDMAUD_CLIENT *pClient) 00218 { 00219 PWDMAUD_CLIENT Client; 00220 PWDMAUD_DEVICE_EXTENSION DeviceExtension; 00221 00222 /* get device extension */ 00223 DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 00224 00225 if (!DeviceExtension->NumSysAudioDevices) 00226 { 00227 /* wdmaud failed to open sysaudio */ 00228 return STATUS_UNSUCCESSFUL; 00229 } 00230 00231 /* sanity check */ 00232 ASSERT(!IsListEmpty(&DeviceExtension->SysAudioDeviceList)); 00233 00234 /* allocate client context struct */ 00235 Client = AllocateItem(NonPagedPool, sizeof(WDMAUD_CLIENT)); 00236 00237 /* check for allocation failure */ 00238 if (!Client) 00239 { 00240 /* not enough memory */ 00241 return STATUS_INSUFFICIENT_RESOURCES; 00242 } 00243 00244 /* zero client context struct */ 00245 RtlZeroMemory(Client, sizeof(WDMAUD_CLIENT)); 00246 00247 /* initialize mixer event list */ 00248 InitializeListHead(&Client->MixerEventList); 00249 00250 /* store result */ 00251 *pClient = Client; 00252 00253 /* insert client into list */ 00254 ExInterlockedInsertTailList(&DeviceExtension->WdmAudClientList, &Client->Entry, &DeviceExtension->Lock); 00255 00256 /* done */ 00257 return STATUS_SUCCESS; 00258 } 00259 00260 00261 Generated on Fri May 25 2012 04:26:54 for ReactOS by
1.7.6.1
|