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

sup.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/sup.c
00005  * PURPOSE:         Misc support routines
00006  * PROGRAMMER:      Andrew Greenwood
00007  *                  Johannes Anderwald
00008  */
00009 #include "wdmaud.h"
00010 
00011 PVOID
00012 AllocateItem(
00013     IN POOL_TYPE PoolType,
00014     IN SIZE_T NumberOfBytes)
00015 {
00016     PVOID Item = ExAllocatePool(PoolType, NumberOfBytes);
00017     if (!Item)
00018         return Item;
00019 
00020     RtlZeroMemory(Item, NumberOfBytes);
00021     return Item;
00022 }
00023 
00024 VOID
00025 FreeItem(
00026     IN PVOID Item)
00027 {
00028     ExFreePool(Item);
00029 }
00030 
00031 
00032 
00033 ULONG
00034 GetSysAudioDeviceCount(
00035     IN  PDEVICE_OBJECT DeviceObject)
00036 {
00037     PWDMAUD_DEVICE_EXTENSION DeviceExtension;
00038     KSPROPERTY Pin;
00039     ULONG Count, BytesReturned;
00040     NTSTATUS Status;
00041 
00042     /* setup the query request */
00043     Pin.Set = KSPROPSETID_Sysaudio;
00044     Pin.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
00045     Pin.Flags = KSPROPERTY_TYPE_GET;
00046 
00047     DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00048 
00049     /* query sysaudio for the device count */
00050     Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned);
00051     if (!NT_SUCCESS(Status))
00052         return 0;
00053 
00054     return Count;
00055 }
00056 
00057 
00058 NTSTATUS
00059 SetIrpIoStatus(
00060     IN PIRP Irp,
00061     IN NTSTATUS Status,
00062     IN ULONG Length)
00063 {
00064     Irp->IoStatus.Information = Length;
00065     Irp->IoStatus.Status = Status;
00066     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00067     return Status;
00068 
00069 }
00070 
00071 ULONG
00072 ClosePin(
00073     IN  PWDMAUD_CLIENT ClientInfo,
00074     IN  ULONG FilterId,
00075     IN  ULONG PinId,
00076     IN  SOUND_DEVICE_TYPE DeviceType)
00077 {
00078     ULONG Index;
00079 
00080     for(Index = 0; Index < ClientInfo->NumPins; Index++)
00081     {
00082         if (ClientInfo->hPins[Index].FilterId == FilterId && ClientInfo->hPins[Index].PinId == PinId && ClientInfo->hPins[Index].Handle && ClientInfo->hPins[Index].Type == DeviceType)
00083         {
00084             if (ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
00085             {
00086                 ZwClose(ClientInfo->hPins[Index].Handle);
00087             }
00088             ClientInfo->hPins[Index].Handle = NULL;
00089             return Index;
00090         }
00091     }
00092     return MAXULONG;
00093 }
00094 
00095 NTSTATUS
00096 InsertPinHandle(
00097     IN  PWDMAUD_CLIENT ClientInfo,
00098     IN  ULONG FilterId,
00099     IN  ULONG PinId,
00100     IN  SOUND_DEVICE_TYPE DeviceType,
00101     IN  HANDLE PinHandle,
00102     IN  ULONG FreeIndex)
00103 {
00104     PWDMAUD_HANDLE Handles;
00105 
00106     if (FreeIndex != MAXULONG)
00107     {
00108         /* re-use a free index */
00109         ClientInfo->hPins[FreeIndex].Handle = PinHandle;
00110         ClientInfo->hPins[FreeIndex].FilterId = FilterId;
00111         ClientInfo->hPins[FreeIndex].PinId = PinId;
00112         ClientInfo->hPins[FreeIndex].Type = DeviceType;
00113 
00114         return STATUS_SUCCESS;
00115     }
00116 
00117     Handles = AllocateItem(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1));
00118 
00119     if (!Handles)
00120         return STATUS_INSUFFICIENT_RESOURCES;
00121 
00122     if (ClientInfo->NumPins)
00123     {
00124         RtlMoveMemory(Handles, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins);
00125         FreeItem(ClientInfo->hPins);
00126     }
00127 
00128     ClientInfo->hPins = Handles;
00129     ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle;
00130     ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceType;
00131     ClientInfo->hPins[ClientInfo->NumPins].FilterId = FilterId;
00132     ClientInfo->hPins[ClientInfo->NumPins].PinId = PinId;
00133     ClientInfo->NumPins++;
00134 
00135     return STATUS_SUCCESS;
00136 }
00137 
00138 PKEY_VALUE_PARTIAL_INFORMATION
00139 ReadKeyValue(
00140     IN HANDLE hSubKey,
00141     IN PUNICODE_STRING KeyName)
00142 {
00143     NTSTATUS Status;
00144     ULONG Length;
00145     PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
00146 
00147     /* now query MatchingDeviceId key */
00148     Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, NULL, 0, &Length);
00149 
00150     /* check for success */
00151     if (Status != STATUS_BUFFER_TOO_SMALL)
00152         return NULL;
00153 
00154     /* allocate a buffer for key data */
00155     PartialInformation = AllocateItem(NonPagedPool, Length);
00156 
00157     if (!PartialInformation)
00158         return NULL;
00159 
00160 
00161     /* now query MatchingDeviceId key */
00162     Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, PartialInformation, Length, &Length);
00163 
00164     /* check for success */
00165     if (!NT_SUCCESS(Status))
00166     {
00167         FreeItem(PartialInformation);
00168         return NULL;
00169     }
00170 
00171     if (PartialInformation->Type != REG_SZ)
00172     {
00173         /* invalid key type */
00174         FreeItem(PartialInformation);
00175         return NULL;
00176     }
00177 
00178     return PartialInformation;
00179 }
00180 
00181 
00182 NTSTATUS
00183 CompareProductName(
00184     IN HANDLE hSubKey,
00185     IN LPWSTR PnpName,
00186     IN ULONG ProductNameSize,
00187     OUT LPWSTR ProductName)
00188 {
00189     PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
00190     UNICODE_STRING DriverDescName = RTL_CONSTANT_STRING(L"DriverDesc");
00191     UNICODE_STRING MatchingDeviceIdName = RTL_CONSTANT_STRING(L"MatchingDeviceId");
00192     ULONG Length;
00193     LPWSTR DeviceName;
00194 
00195     /* read MatchingDeviceId value */
00196     PartialInformation = ReadKeyValue(hSubKey, &MatchingDeviceIdName);
00197 
00198     if (!PartialInformation)
00199         return STATUS_UNSUCCESSFUL;
00200 
00201 
00202     /* extract last '&' */
00203     DeviceName = wcsrchr((LPWSTR)PartialInformation->Data, L'&');
00204     ASSERT(DeviceName);
00205     /* terminate it */
00206     DeviceName[0] = L'\0';
00207 
00208     Length = wcslen((LPWSTR)PartialInformation->Data);
00209 
00210     DPRINT("DeviceName %S PnpName %S Length %u\n", (LPWSTR)PartialInformation->Data, PnpName, Length);
00211 
00212     if (_wcsnicmp((LPWSTR)PartialInformation->Data, &PnpName[4], Length))
00213     {
00214         FreeItem(PartialInformation);
00215         return STATUS_NO_MATCH;
00216     }
00217 
00218     /* free buffer */
00219     FreeItem(PartialInformation);
00220 
00221     /* read DriverDescName value */
00222     PartialInformation = ReadKeyValue(hSubKey, &DriverDescName);
00223 
00224     if (!PartialInformation)
00225     {
00226         /* failed to read driver desc key */
00227         return STATUS_UNSUCCESSFUL;
00228     }
00229 
00230     /* copy key name */
00231     Length = min(ProductNameSize * sizeof(WCHAR), PartialInformation->DataLength);
00232     RtlMoveMemory(ProductName, (PVOID)PartialInformation->Data, Length);
00233 
00234     /* zero terminate it */
00235     ProductName[ProductNameSize-1] = L'\0';
00236 
00237     /* free buffer */
00238     FreeItem(PartialInformation);
00239 
00240     return STATUS_SUCCESS;
00241 }
00242 
00243 
00244 
00245 NTSTATUS
00246 FindProductName(
00247     IN LPWSTR PnpName,
00248     IN ULONG ProductNameSize,
00249     OUT LPWSTR ProductName)
00250 {
00251     UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E96C-E325-11CE-BFC1-08002BE10318}");
00252 
00253     UNICODE_STRING SubKeyName;
00254     WCHAR SubKey[20];
00255     OBJECT_ATTRIBUTES ObjectAttributes;
00256     HANDLE hKey, hSubKey;
00257     NTSTATUS Status;
00258     ULONG Length, Index;
00259     PKEY_FULL_INFORMATION KeyInformation;
00260 
00261     for(Index = 0; Index < wcslen(PnpName); Index++)
00262     {
00263         if (PnpName[Index] == '#')
00264             PnpName[Index] = L'\\';
00265     }
00266 
00267 
00268     /* initialize key attributes */
00269     InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, NULL, NULL);
00270 
00271     /* open the key */
00272     Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
00273 
00274     /* check for success */
00275     if (!NT_SUCCESS(Status))
00276         return Status;
00277 
00278     /* query num of subkeys */
00279     Status = ZwQueryKey(hKey, KeyFullInformation, NULL, 0, &Length);
00280 
00281     if (Status != STATUS_BUFFER_TOO_SMALL)
00282     {
00283         DPRINT1("ZwQueryKey failed with %x\n", Status);
00284         /* failed */
00285         ZwClose(hKey);
00286         return Status;
00287     }
00288 
00289     /* allocate key information struct */
00290     KeyInformation = AllocateItem(NonPagedPool, Length);
00291     if (!KeyInformation)
00292     {
00293         /* no memory */
00294         ZwClose(hKey);
00295         return STATUS_INSUFFICIENT_RESOURCES;
00296     }
00297 
00298     /* query num of subkeys */
00299     Status = ZwQueryKey(hKey, KeyFullInformation, (PVOID)KeyInformation, Length, &Length);
00300 
00301     if (!NT_SUCCESS(Status))
00302     {
00303         DPRINT1("ZwQueryKey failed with %x\n", Status);
00304         FreeItem(KeyInformation);
00305         ZwClose(hKey);
00306         return Status;
00307     }
00308 
00309     /* now iterate through all subkeys */
00310     for(Index = 0; Index < KeyInformation->SubKeys; Index++)
00311     {
00312         /* subkeys are always in the format 0000-XXXX */
00313         swprintf(SubKey, L"%04u", Index);
00314 
00315         /* initialize subkey name */
00316         RtlInitUnicodeString(&SubKeyName, SubKey);
00317 
00318         /* initialize key attributes */
00319         InitializeObjectAttributes(&ObjectAttributes, &SubKeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, hKey, NULL);
00320 
00321         /* open the sub key */
00322         Status = ZwOpenKey(&hSubKey, GENERIC_READ, &ObjectAttributes);
00323 
00324         /* check for success */
00325         if (NT_SUCCESS(Status))
00326         {
00327             /* compare product name */
00328             Status = CompareProductName(hSubKey, PnpName, ProductNameSize, ProductName);
00329 
00330             /* close subkey */
00331             ZwClose(hSubKey);
00332 
00333             if (NT_SUCCESS(Status))
00334                 break;
00335         }
00336     }
00337 
00338     /* free buffer */
00339     FreeItem(KeyInformation);
00340 
00341     /* close key */
00342     ZwClose(hKey);
00343 
00344     /* no matching key found */
00345     return Status;
00346 }
00347 
00348 NTSTATUS
00349 GetSysAudioDevicePnpName(
00350     IN  PDEVICE_OBJECT DeviceObject,
00351     IN  ULONG DeviceIndex,
00352     OUT LPWSTR * Device)
00353 {
00354     ULONG BytesReturned;
00355     KSP_PIN Pin;
00356     NTSTATUS Status;
00357     PWDMAUD_DEVICE_EXTENSION DeviceExtension;
00358 
00359    /* first check if the device index is within bounds */
00360    if (DeviceIndex >= GetSysAudioDeviceCount(DeviceObject))
00361        return STATUS_INVALID_PARAMETER;
00362 
00363     /* setup the query request */
00364     Pin.Property.Set = KSPROPSETID_Sysaudio;
00365     Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME;
00366     Pin.Property.Flags = KSPROPERTY_TYPE_GET;
00367     Pin.PinId = DeviceIndex;
00368 
00369     DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00370 
00371     /* query sysaudio for the device path */
00372     Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), NULL, 0, &BytesReturned);
00373 
00374     /* check if the request failed */
00375     if (Status != STATUS_BUFFER_TOO_SMALL || BytesReturned == 0)
00376         return STATUS_UNSUCCESSFUL;
00377 
00378     /* allocate buffer for the device */
00379     *Device = AllocateItem(NonPagedPool, BytesReturned);
00380     if (!Device)
00381         return STATUS_INSUFFICIENT_RESOURCES;
00382 
00383     /* query sysaudio again for the device path */
00384     Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), (PVOID)*Device, BytesReturned, &BytesReturned);
00385 
00386     if (!NT_SUCCESS(Status))
00387     {
00388         /* failed */
00389         FreeItem(*Device);
00390         return Status;
00391     }
00392 
00393     return Status;
00394 }
00395 
00396 NTSTATUS
00397 OpenDevice(
00398     IN LPWSTR Device,
00399     OUT PHANDLE DeviceHandle,
00400     OUT PFILE_OBJECT * FileObject)
00401 {
00402     NTSTATUS Status;
00403     HANDLE hDevice;
00404 
00405     /* now open the device */
00406     Status = WdmAudOpenSysAudioDevice(Device, &hDevice);
00407 
00408     if (!NT_SUCCESS(Status))
00409     {
00410         return Status;
00411     }
00412 
00413     *DeviceHandle = hDevice;
00414 
00415     if (FileObject)
00416     {
00417         Status = ObReferenceObjectByHandle(hDevice, FILE_READ_DATA | FILE_WRITE_DATA, IoFileObjectType, KernelMode, (PVOID*)FileObject, NULL);
00418 
00419         if (!NT_SUCCESS(Status))
00420         {
00421             ZwClose(hDevice);
00422         }
00423     }
00424 
00425     return Status;
00426 
00427 }

Generated on Sun May 27 2012 04:28:40 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.