/reactos/sdk/lib/drivers/sound/mmebuddy/kernel.c

https://gitlab.com/dj-tech/reactos · C · 132 lines · 79 code · 22 blank · 31 comment · 8 complexity · 37bb6ff18e397b7c1629db378eb8968b MD5 · raw file

  1. /*
  2. * PROJECT: ReactOS Sound System "MME Buddy" Library
  3. * LICENSE: GPL - See COPYING in the top level directory
  4. * FILE: lib/drivers/sound/mmebuddy/kernel.c
  5. *
  6. * PURPOSE: Routines assisting with device I/O between user-mode and
  7. * kernel-mode.
  8. *
  9. * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
  10. */
  11. #include "precomp.h"
  12. /*
  13. Wraps around CreateFile in order to provide a simpler interface tailored
  14. towards sound driver support code. This simply takes a device path and
  15. opens the device in either read-only mode, or read/write mode (depending on
  16. the ReadOnly parameter).
  17. If the device is opened in read/write mode, it is opened for overlapped I/O.
  18. */
  19. MMRESULT
  20. OpenKernelSoundDeviceByName(
  21. IN PWSTR DevicePath,
  22. IN BOOLEAN ReadOnly,
  23. OUT PHANDLE Handle)
  24. {
  25. DWORD AccessRights;
  26. VALIDATE_MMSYS_PARAMETER( DevicePath );
  27. VALIDATE_MMSYS_PARAMETER( Handle );
  28. AccessRights = ReadOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE;
  29. SND_TRACE(L"OpenKernelSoundDeviceByName: %wS\n", DevicePath);
  30. *Handle = CreateFile(DevicePath,
  31. AccessRights,
  32. FILE_SHARE_WRITE, /* FIXME? Should be read also? */
  33. NULL,
  34. OPEN_EXISTING,
  35. ReadOnly ? 0 : FILE_FLAG_OVERLAPPED,
  36. NULL);
  37. if ( *Handle == INVALID_HANDLE_VALUE )
  38. {
  39. SND_ERR(L"CreateFile filed - winerror %d\n", GetLastError());
  40. return Win32ErrorToMmResult(GetLastError());
  41. }
  42. return MMSYSERR_NOERROR;
  43. }
  44. /*
  45. Just a wrapped around CloseHandle.
  46. */
  47. MMRESULT
  48. CloseKernelSoundDevice(
  49. IN HANDLE Handle)
  50. {
  51. VALIDATE_MMSYS_PARAMETER( Handle );
  52. CloseHandle(Handle);
  53. return MMSYSERR_NOERROR;
  54. }
  55. /*
  56. This is a wrapper around DeviceIoControl which provides control over
  57. instantiated sound devices. It waits for I/O to complete (since an
  58. instantiated sound device is opened in overlapped mode, this is necessary).
  59. */
  60. MMRESULT
  61. SyncOverlappedDeviceIoControl(
  62. IN HANDLE Handle,
  63. IN DWORD IoControlCode,
  64. IN LPVOID InBuffer,
  65. IN DWORD InBufferSize,
  66. OUT LPVOID OutBuffer,
  67. IN DWORD OutBufferSize,
  68. OUT LPDWORD BytesTransferred OPTIONAL)
  69. {
  70. OVERLAPPED Overlapped;
  71. BOOLEAN IoResult;
  72. DWORD Transferred;
  73. /* Overlapped I/O is done here - this is used for waiting for completion */
  74. ZeroMemory(&Overlapped, sizeof(OVERLAPPED));
  75. Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  76. if ( ! Overlapped.hEvent )
  77. return Win32ErrorToMmResult(GetLastError());
  78. /* Talk to the device */
  79. IoResult = DeviceIoControl(Handle,
  80. IoControlCode,
  81. InBuffer,
  82. InBufferSize,
  83. OutBuffer,
  84. OutBufferSize,
  85. NULL,
  86. &Overlapped);
  87. /* If failure occurs, make sure it's not just due to the overlapped I/O */
  88. if ( ! IoResult )
  89. {
  90. if ( GetLastError() != ERROR_IO_PENDING )
  91. {
  92. CloseHandle(Overlapped.hEvent);
  93. return Win32ErrorToMmResult(GetLastError());
  94. }
  95. }
  96. /* Wait for the I/O to complete */
  97. IoResult = GetOverlappedResult(Handle,
  98. &Overlapped,
  99. &Transferred,
  100. TRUE);
  101. /* Don't need this any more */
  102. CloseHandle(Overlapped.hEvent);
  103. if ( ! IoResult )
  104. return Win32ErrorToMmResult(GetLastError());
  105. SND_TRACE(L"Transferred %d bytes in Sync overlapped I/O\n", Transferred);
  106. if ( BytesTransferred )
  107. *BytesTransferred = Transferred;
  108. return MMSYSERR_NOERROR;
  109. }