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.

288 lines
8.1 KiB

  1. /****************************************************************************
  2. *
  3. * util.c
  4. *
  5. * Copyright (c) 1992-1999 Microsoft Corporation
  6. *
  7. ***************************************************************************/
  8. #include "winmmi.h"
  9. //
  10. // Assist with unicode conversions
  11. //
  12. // This function translates from Unicode strings to multibyte strings.
  13. // It will automatically munge down the Unicode string until the translation
  14. // is guaranteed to succeed with the buffer space available in the multibyte
  15. // buffer. Then it performs the conversion.
  16. int Iwcstombs(LPSTR lpstr, LPCWSTR lpwstr, int len)
  17. {
  18. int wlength;
  19. wlength=wcslen(lpwstr)+1;
  20. while (WideCharToMultiByte(GetACP(), 0, lpwstr, wlength, NULL, 0, NULL, NULL)>len && wlength>0) {
  21. wlength--;
  22. }
  23. return WideCharToMultiByte(GetACP(), 0, lpwstr, wlength, lpstr, len, NULL, NULL);
  24. }
  25. int Imbstowcs(LPWSTR lpwstr, LPCSTR lpstr, int len)
  26. {
  27. return MultiByteToWideChar(GetACP(),
  28. MB_PRECOMPOSED,
  29. lpstr,
  30. -1,
  31. lpwstr,
  32. len);
  33. }
  34. #if 0
  35. BOOL HugePageLock(LPVOID lpArea, DWORD dwLength)
  36. {
  37. PVOID BaseAddress = lpArea;
  38. ULONG RegionSize = dwLength;
  39. NTSTATUS Status;
  40. Status =
  41. NtLockVirtualMemory(NtCurrentProcess(),
  42. &BaseAddress,
  43. &RegionSize,
  44. MAP_PROCESS);
  45. //
  46. // People without the right priviledge will not have the luxury
  47. // of having their pages locked
  48. // (maybe we should do something else to commit it ?)
  49. //
  50. if (!NT_SUCCESS(Status) && Status != STATUS_PRIVILEGE_NOT_HELD) {
  51. dprintf2(("Failed to lock virtual memory - code %X", Status));
  52. return FALSE;
  53. }
  54. return TRUE;
  55. }
  56. void HugePageUnlock(LPVOID lpArea, DWORD dwLength)
  57. {
  58. PVOID BaseAddress = lpArea;
  59. ULONG RegionSize = dwLength;
  60. NTSTATUS Status;
  61. Status =
  62. NtUnlockVirtualMemory(NtCurrentProcess(),
  63. &BaseAddress,
  64. &RegionSize,
  65. MAP_PROCESS);
  66. //
  67. // People without the right priviledge will not have the luxury
  68. // of having their pages locked
  69. // (maybe we should do something else to commit it ?)
  70. //
  71. if (!NT_SUCCESS(Status) && Status != STATUS_PRIVILEGE_NOT_HELD) {
  72. dprintf2(("Failed to unlock virtual memory - code %X", Status));
  73. }
  74. }
  75. #endif
  76. /****************************************************************************
  77. *
  78. * @doc DDK MMSYSTEM
  79. *
  80. * @api BOOL | DriverCallback | This function notifies a client
  81. * application by sending a message to a window or callback
  82. * function or by unblocking a task.
  83. *
  84. * @parm DWORD | dwCallBack | Specifies either the address of
  85. * a callback function, a window handle, or a task handle, depending on
  86. * the flags specified in the <p wFlags> parameter.
  87. *
  88. * @parm DWORD | dwFlags | Specifies how the client
  89. * application is notified, according to one of the following flags:
  90. *
  91. * @flag DCB_FUNCTION | The application is notified by
  92. * sending a message to a callback function. The <p dwCallback>
  93. * parameter specifies a procedure-instance address.
  94. * @flag DCB_WINDOW | The application is notified by
  95. * sending a message to a window. The low-order word of the
  96. * <p dwCallback> parameter specifies a window handle.
  97. * @flag DCB_TASK | The application is notified by
  98. * calling mmTaskSignal
  99. * @flag DCB_EVENT | The application is notified by
  100. * calling SetEvent on the (assumed) event handle
  101. *
  102. * @parm HANDLE | hDevice | Specifies a handle to the device
  103. * associated with the notification. This is the handle assigned by
  104. * MMSYSTEM when the device was opened.
  105. *
  106. * @parm DWORD | dwMsg | Specifies a message to send to the
  107. * application.
  108. *
  109. * @parm DWORD | dwUser | Specifies the DWORD of user instance
  110. * data supplied by the application when the device was opened.
  111. *
  112. * @parm DWORD | dwParam1 | Specifies a message-dependent parameter.
  113. * @parm DWORD | dwParam2 | Specifies a message-dependent parameter.
  114. *
  115. * @rdesc Returns TRUE if the callback was performed, else FALSE if an invalid
  116. * parameter was passed, or the task's message queue was full.
  117. *
  118. * @comm This function can be called from an APC routine.
  119. *
  120. * The flags DCB_FUNCTION and DCB_WINDOW are equivalent to the
  121. * high-order word of the corresponding flags CALLBACK_FUNCTION
  122. * and CALLBACK_WINDOW specified when the device was opened.
  123. *
  124. * If notification is done with a callback function, <p hDevice>,
  125. * <p wMsg>, <p dwUser>, <p dwParam1>, and <p dwParam2> are passed to
  126. * the callback. If notification is done with a window, only <p wMsg>,
  127. * <p hDevice>, and <p dwParam1> are passed to the window.
  128. ***************************************************************************/
  129. BOOL APIENTRY DriverCallback(DWORD_PTR dwCallBack,
  130. DWORD dwFlags,
  131. HDRVR hDrv,
  132. DWORD dwMsg,
  133. DWORD_PTR dwUser,
  134. DWORD_PTR dw1,
  135. DWORD_PTR dw2)
  136. {
  137. //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  138. // if this is a MIM_DATA message, and thruing is enabled for this
  139. // device, pass the data on the the thru device
  140. // NOTE: we do this BEFORE we check for NULL callback type on purpose!
  141. //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  142. //
  143. // if this is not a MIM_DATA message, or if we have no
  144. // thruing handle installed in the midi in device,
  145. // we can skip all of the midi thruing code
  146. //
  147. if ((dwMsg == MIM_DATA) && (HtoPT(PMIDIDEV,hDrv)->pmThru))
  148. {
  149. MMRESULT mmr;
  150. mmr = midiOutShortMsg((HMIDIOUT)HtoPT(PMIDIDEV,hDrv)->pmThru, (DWORD)dw1);
  151. if (MIDIERR_DONT_CONTINUE == mmr)
  152. {
  153. return FALSE;
  154. }
  155. if (MMSYSERR_INVALHANDLE == mmr)
  156. {
  157. HtoPT(PMIDIDEV,hDrv)->pmThru = NULL;
  158. }
  159. }
  160. //
  161. // If the callback routine is null or erroneous flags are set return
  162. // at once
  163. //
  164. if (dwCallBack == 0L) {
  165. return FALSE;
  166. }
  167. //
  168. // Test what type of callback we're to make
  169. //
  170. switch (dwFlags & DCB_TYPEMASK) {
  171. case DCB_WINDOW:
  172. //
  173. // Send message to window
  174. //
  175. return PostMessage(*(HWND *)&dwCallBack, dwMsg, (WPARAM)hDrv, (LPARAM)dw1);
  176. case DCB_TASK:
  177. //
  178. // Send message to task
  179. //
  180. PostThreadMessage((DWORD)dwCallBack, dwMsg, (WPARAM)hDrv, (LPARAM)dw1);
  181. return mmTaskSignal((DWORD)dwCallBack);
  182. case DCB_FUNCTION:
  183. //
  184. // Call back the user's callback
  185. //
  186. (**(PDRVCALLBACK *)&dwCallBack)(hDrv, dwMsg, dwUser, dw1, dw2);
  187. return TRUE;
  188. case DCB_EVENT:
  189. //
  190. // Signal the user's event
  191. //
  192. SetEvent((HANDLE)dwCallBack);
  193. return TRUE;
  194. default:
  195. return FALSE;
  196. }
  197. }
  198. /*
  199. * @doc INTERNAL MCI
  200. * @api PVOID | mciAlloc | Allocate memory from our heap and zero it
  201. *
  202. * @parm DWORD | cb | The amount of memory to allocate
  203. *
  204. * @rdesc returns pointer to the new memory
  205. *
  206. */
  207. PVOID winmmAlloc(DWORD cb)
  208. {
  209. PVOID ptr;
  210. ptr = (PVOID)HeapAlloc(hHeap, 0, cb);
  211. if (ptr == NULL) {
  212. return NULL;
  213. } else {
  214. ZeroMemory(ptr, cb);
  215. return ptr;
  216. }
  217. }
  218. /*
  219. * @doc INTERNAL MCI
  220. * @api PVOID | mciReAlloc | ReAllocate memory from our heap and zero extra
  221. *
  222. * @parm DWORD | cb | The new size
  223. *
  224. * @rdesc returns pointer to the new memory
  225. *
  226. */
  227. PVOID winmmReAlloc(PVOID ptr, DWORD cb)
  228. {
  229. PVOID newptr;
  230. DWORD oldcb;
  231. newptr = (PVOID)HeapAlloc(hHeap, 0, cb);
  232. if (newptr != NULL) {
  233. oldcb = (DWORD)HeapSize(hHeap, 0, ptr);
  234. if (oldcb<cb) { // Block is being expanded
  235. ZeroMemory((PBYTE)newptr+oldcb, cb-oldcb);
  236. cb = oldcb;
  237. }
  238. CopyMemory(newptr, ptr, cb);
  239. HeapFree(hHeap, 0, ptr);
  240. }
  241. return newptr;
  242. }