Leaked source code of windows server 2003
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.

213 lines
6.1 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: base.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * Contains private versions of routines that used to be in kernel32.dll
  7. *
  8. * History:
  9. * 12-16-94 JimA Created.
  10. \***************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include <ntddbeep.h>
  14. /***************************************************************************\
  15. * RtlLoadStringOrError
  16. *
  17. * NOTE: Passing a NULL value for lpch returns the string length. (WRONG!)
  18. *
  19. * Warning: The return count does not include the terminating NULL WCHAR;
  20. *
  21. * History:
  22. * 04-05-91 ScottLu Fixed - code is now shared between client and server
  23. * 09-24-90 MikeKe From Win30
  24. * 12-09-94 JimA Use message table.
  25. \***************************************************************************/
  26. int RtlLoadStringOrError(
  27. UINT wID,
  28. LPWSTR lpBuffer, // Unicode buffer
  29. int cchBufferMax, // cch in Unicode buffer
  30. WORD wLangId)
  31. {
  32. PMESSAGE_RESOURCE_ENTRY MessageEntry;
  33. int cch;
  34. NTSTATUS Status;
  35. /*
  36. * Make sure the parms are valid.
  37. */
  38. if (!lpBuffer || (cchBufferMax-- == 0))
  39. return 0;
  40. cch = 0;
  41. Status = RtlFindMessage((PVOID)hModuleWin, (ULONG_PTR)RT_MESSAGETABLE,
  42. wLangId, wID, &MessageEntry);
  43. if (NT_SUCCESS(Status)) {
  44. /*
  45. * Copy out the message. If the whole thing can be copied,
  46. * copy two fewer chars so the crlf in the message will be
  47. * stripped out.
  48. */
  49. cch = wcslen((PWCHAR)MessageEntry->Text) - 2;
  50. if (cch > cchBufferMax)
  51. cch = cchBufferMax;
  52. RtlCopyMemory(lpBuffer, (PWCHAR)MessageEntry->Text, cch * sizeof(WCHAR));
  53. }
  54. /*
  55. * Append a NULL.
  56. */
  57. lpBuffer[cch] = 0;
  58. return cch;
  59. }
  60. /***************************************************************************\
  61. * UserSleep
  62. *
  63. * Kernel-mode version of Sleep() that must have a timeout value and
  64. * is not alertable.
  65. *
  66. * History:
  67. * 12-11-94 JimA Created.
  68. \***************************************************************************/
  69. VOID UserSleep(
  70. DWORD dwMilliseconds)
  71. {
  72. LARGE_INTEGER TimeOut;
  73. TimeOut.QuadPart = Int32x32To64( dwMilliseconds, -10000 );
  74. KeDelayExecutionThread(UserMode, FALSE, &TimeOut);
  75. }
  76. /***************************************************************************\
  77. * UserBeep
  78. *
  79. * Kernel-mode version of Beep().
  80. *
  81. * History:
  82. * 12-16-94 JimA Created.
  83. \***************************************************************************/
  84. BOOL UserBeep(
  85. DWORD dwFreq,
  86. DWORD dwDuration)
  87. {
  88. OBJECT_ATTRIBUTES ObjectAttributes;
  89. UNICODE_STRING NameString;
  90. NTSTATUS Status;
  91. IO_STATUS_BLOCK IoStatus;
  92. BEEP_SET_PARAMETERS BeepParameters;
  93. HANDLE hBeepDevice;
  94. LARGE_INTEGER TimeOut;
  95. CheckCritOut();
  96. if (IsRemoteConnection()) {
  97. if (gpRemoteBeepDevice == NULL)
  98. Status = STATUS_UNSUCCESSFUL;
  99. else
  100. Status = ObOpenObjectByPointer(
  101. gpRemoteBeepDevice,
  102. 0,
  103. NULL,
  104. EVENT_ALL_ACCESS,
  105. NULL,
  106. KernelMode,
  107. &hBeepDevice);
  108. } else {
  109. RtlInitUnicodeString(&NameString, DD_BEEP_DEVICE_NAME_U);
  110. InitializeObjectAttributes(&ObjectAttributes,
  111. &NameString,
  112. OBJ_KERNEL_HANDLE,
  113. NULL,
  114. NULL);
  115. Status = ZwCreateFile(&hBeepDevice,
  116. FILE_READ_DATA | FILE_WRITE_DATA,
  117. &ObjectAttributes,
  118. &IoStatus,
  119. NULL,
  120. 0,
  121. FILE_SHARE_READ | FILE_SHARE_WRITE,
  122. FILE_OPEN_IF,
  123. 0,
  124. (PVOID) NULL,
  125. 0L);
  126. }
  127. if (!NT_SUCCESS(Status)) {
  128. return FALSE;
  129. }
  130. /*
  131. * 0,0 is a special case used to turn off a beep. Otherwise
  132. * validate the dwFreq parameter to be in range.
  133. */
  134. if ((dwFreq != 0 || dwDuration != 0) &&
  135. (dwFreq < (ULONG)0x25 || dwFreq > (ULONG)0x7FFF)) {
  136. Status = STATUS_INVALID_PARAMETER;
  137. } else {
  138. BeepParameters.Frequency = dwFreq;
  139. BeepParameters.Duration = dwDuration;
  140. Status = ZwDeviceIoControlFile(hBeepDevice,
  141. NULL,
  142. NULL,
  143. NULL,
  144. &IoStatus,
  145. IOCTL_BEEP_SET,
  146. &BeepParameters,
  147. sizeof(BeepParameters),
  148. NULL,
  149. 0);
  150. }
  151. EnterCrit();
  152. _UserSoundSentryWorker();
  153. LeaveCrit();
  154. if (!NT_SUCCESS(Status)) {
  155. ZwClose(hBeepDevice);
  156. return FALSE;
  157. }
  158. /*
  159. * Beep device is asynchronous, so sleep for duration
  160. * to allow this beep to complete.
  161. */
  162. if (dwDuration != (DWORD)-1 && (dwFreq != 0 || dwDuration != 0)) {
  163. TimeOut.QuadPart = Int32x32To64( dwDuration, -10000);
  164. KeDelayExecutionThread(UserMode, FALSE, &TimeOut);
  165. }
  166. ZwClose(hBeepDevice);
  167. return TRUE;
  168. }
  169. void RtlInitUnicodeStringOrId(
  170. PUNICODE_STRING pstrName,
  171. LPWSTR lpstrName)
  172. {
  173. if (IS_PTR(lpstrName)) {
  174. RtlInitUnicodeString(pstrName, lpstrName);
  175. } else {
  176. pstrName->Length = pstrName->MaximumLength = 0;
  177. pstrName->Buffer = lpstrName;
  178. }
  179. }