Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
2.6 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. NewShenDiaoXiaLv.cpp
  5. Abstract:
  6. On NT, when there is no CD in the CDROM, and the app sends a MCI_OPEN
  7. command to the CDAUDIO device, the app has fully exclusive control of the
  8. CDROM. When later on user inserts CD, the app will not receive
  9. WM_DEVICECHANGE message. And this app relies on the message to know if
  10. there is a new CD inserted.
  11. The fix is check whether the CD is there when we do MCI_OPEN command, if
  12. there is not CD, we will close the device.
  13. Notes:
  14. This is an app specific shim.
  15. History:
  16. 05/28/2001 xiaoz Created
  17. --*/
  18. #include "precomp.h"
  19. IMPLEMENT_SHIM_BEGIN(NewShenDiaoXiaLv)
  20. #include "ShimHookMacro.h"
  21. APIHOOK_ENUM_BEGIN
  22. APIHOOK_ENUM_ENTRY(mciSendCommandA)
  23. APIHOOK_ENUM_END
  24. /*++
  25. Close the device if we get hardware error(CD is not there).
  26. --*/
  27. MCIERROR
  28. APIHOOK(mciSendCommandA)(
  29. MCIDEVICEID IDDevice,
  30. UINT uMsg,
  31. DWORD fdwCommand,
  32. DWORD dwParam
  33. )
  34. {
  35. MCIERROR mciErr, mciError;
  36. MCI_STATUS_PARMS mciStatus;
  37. LPMCI_OPEN_PARMSA lpmciOpenParam;
  38. CString cstrDeviveType;
  39. mciErr = ORIGINAL_API(mciSendCommandA)(IDDevice, uMsg, fdwCommand, dwParam);
  40. // We are only interested in a successful MCI_OPEN Message
  41. if (mciErr || (uMsg != MCI_OPEN) || IsBadReadPtr((CONST VOID*)(ULONG_PTR)dwParam, 1))
  42. {
  43. goto End;
  44. }
  45. // We are only interested in MCI message sent to CDAUDIO
  46. lpmciOpenParam = (LPMCI_OPEN_PARMSA) dwParam;
  47. if ((ULONG_PTR) lpmciOpenParam->lpstrDeviceType <= 0xffff)
  48. {
  49. if ((ULONG_PTR)lpmciOpenParam->lpstrDeviceType != MCI_DEVTYPE_CD_AUDIO)
  50. {
  51. goto End;
  52. }
  53. }
  54. else
  55. {
  56. CString cstrDeviveType(lpmciOpenParam->lpstrDeviceType);
  57. if (cstrDeviveType.CompareNoCase(L"cdaudio"))
  58. {
  59. goto End;
  60. }
  61. }
  62. // Send an MCI_STATUS
  63. mciStatus.dwItem = MCI_STATUS_LENGTH ;
  64. mciError = mciSendCommandA(lpmciOpenParam->wDeviceID, MCI_STATUS,
  65. MCI_STATUS_ITEM | MCI_TRACK | MCI_WAIT, (DWORD_PTR) &mciStatus);
  66. if (MCIERR_HARDWARE == mciError)
  67. {
  68. //
  69. // If we get hardware error, it means CD is not there, close the device
  70. // and return error
  71. //
  72. mciSendCommandA(lpmciOpenParam->wDeviceID, MCI_CLOSE, 0, 0);
  73. mciErr = MCIERR_DEVICE_NOT_READY;
  74. }
  75. End:
  76. return mciErr;
  77. }
  78. /*++
  79. Register hooked functions
  80. --*/
  81. HOOK_BEGIN
  82. APIHOOK_ENTRY(WINMM.DLL, mciSendCommandA)
  83. HOOK_END
  84. IMPLEMENT_SHIM_END