/**************************************************************************** * * util.c * * Copyright (c) 1992-1999 Microsoft Corporation * ***************************************************************************/ #include "winmmi.h" // // Assist with unicode conversions // // This function translates from Unicode strings to multibyte strings. // It will automatically munge down the Unicode string until the translation // is guaranteed to succeed with the buffer space available in the multibyte // buffer. Then it performs the conversion. int Iwcstombs(LPSTR lpstr, LPCWSTR lpwstr, int len) { int wlength; wlength=wcslen(lpwstr)+1; while (WideCharToMultiByte(GetACP(), 0, lpwstr, wlength, NULL, 0, NULL, NULL)>len && wlength>0) { wlength--; } return WideCharToMultiByte(GetACP(), 0, lpwstr, wlength, lpstr, len, NULL, NULL); } int Imbstowcs(LPWSTR lpwstr, LPCSTR lpstr, int len) { return MultiByteToWideChar(GetACP(), MB_PRECOMPOSED, lpstr, -1, lpwstr, len); } #if 0 BOOL HugePageLock(LPVOID lpArea, DWORD dwLength) { PVOID BaseAddress = lpArea; ULONG RegionSize = dwLength; NTSTATUS Status; Status = NtLockVirtualMemory(NtCurrentProcess(), &BaseAddress, &RegionSize, MAP_PROCESS); // // People without the right priviledge will not have the luxury // of having their pages locked // (maybe we should do something else to commit it ?) // if (!NT_SUCCESS(Status) && Status != STATUS_PRIVILEGE_NOT_HELD) { dprintf2(("Failed to lock virtual memory - code %X", Status)); return FALSE; } return TRUE; } void HugePageUnlock(LPVOID lpArea, DWORD dwLength) { PVOID BaseAddress = lpArea; ULONG RegionSize = dwLength; NTSTATUS Status; Status = NtUnlockVirtualMemory(NtCurrentProcess(), &BaseAddress, &RegionSize, MAP_PROCESS); // // People without the right priviledge will not have the luxury // of having their pages locked // (maybe we should do something else to commit it ?) // if (!NT_SUCCESS(Status) && Status != STATUS_PRIVILEGE_NOT_HELD) { dprintf2(("Failed to unlock virtual memory - code %X", Status)); } } #endif /**************************************************************************** * * @doc DDK MMSYSTEM * * @api BOOL | DriverCallback | This function notifies a client * application by sending a message to a window or callback * function or by unblocking a task. * * @parm DWORD | dwCallBack | Specifies either the address of * a callback function, a window handle, or a task handle, depending on * the flags specified in the

parameter. * * @parm DWORD | dwFlags | Specifies how the client * application is notified, according to one of the following flags: * * @flag DCB_FUNCTION | The application is notified by * sending a message to a callback function. The

* parameter specifies a procedure-instance address. * @flag DCB_WINDOW | The application is notified by * sending a message to a window. The low-order word of the *

parameter specifies a window handle. * @flag DCB_TASK | The application is notified by * calling mmTaskSignal * @flag DCB_EVENT | The application is notified by * calling SetEvent on the (assumed) event handle * * @parm HANDLE | hDevice | Specifies a handle to the device * associated with the notification. This is the handle assigned by * MMSYSTEM when the device was opened. * * @parm DWORD | dwMsg | Specifies a message to send to the * application. * * @parm DWORD | dwUser | Specifies the DWORD of user instance * data supplied by the application when the device was opened. * * @parm DWORD | dwParam1 | Specifies a message-dependent parameter. * @parm DWORD | dwParam2 | Specifies a message-dependent parameter. * * @rdesc Returns TRUE if the callback was performed, else FALSE if an invalid * parameter was passed, or the task's message queue was full. * * @comm This function can be called from an APC routine. * * The flags DCB_FUNCTION and DCB_WINDOW are equivalent to the * high-order word of the corresponding flags CALLBACK_FUNCTION * and CALLBACK_WINDOW specified when the device was opened. * * If notification is done with a callback function,

, *

,

,

, and

are passed to * the callback. If notification is done with a window, only

, *

, and

are passed to the window. ***************************************************************************/ BOOL APIENTRY DriverCallback(DWORD_PTR dwCallBack, DWORD dwFlags, HDRVR hDrv, DWORD dwMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; // if this is a MIM_DATA message, and thruing is enabled for this // device, pass the data on the the thru device // NOTE: we do this BEFORE we check for NULL callback type on purpose! //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -; // // if this is not a MIM_DATA message, or if we have no // thruing handle installed in the midi in device, // we can skip all of the midi thruing code // if ((dwMsg == MIM_DATA) && (HtoPT(PMIDIDEV,hDrv)->pmThru)) { MMRESULT mmr; mmr = midiOutShortMsg((HMIDIOUT)HtoPT(PMIDIDEV,hDrv)->pmThru, (DWORD)dw1); if (MIDIERR_DONT_CONTINUE == mmr) { return FALSE; } if (MMSYSERR_INVALHANDLE == mmr) { HtoPT(PMIDIDEV,hDrv)->pmThru = NULL; } } // // If the callback routine is null or erroneous flags are set return // at once // if (dwCallBack == 0L) { return FALSE; } // // Test what type of callback we're to make // switch (dwFlags & DCB_TYPEMASK) { case DCB_WINDOW: // // Send message to window // return PostMessage(*(HWND *)&dwCallBack, dwMsg, (WPARAM)hDrv, (LPARAM)dw1); case DCB_TASK: // // Send message to task // PostThreadMessage((DWORD)dwCallBack, dwMsg, (WPARAM)hDrv, (LPARAM)dw1); return mmTaskSignal((DWORD)dwCallBack); case DCB_FUNCTION: // // Call back the user's callback // (**(PDRVCALLBACK *)&dwCallBack)(hDrv, dwMsg, dwUser, dw1, dw2); return TRUE; case DCB_EVENT: // // Signal the user's event // SetEvent((HANDLE)dwCallBack); return TRUE; default: return FALSE; } } /* * @doc INTERNAL MCI * @api PVOID | mciAlloc | Allocate memory from our heap and zero it * * @parm DWORD | cb | The amount of memory to allocate * * @rdesc returns pointer to the new memory * */ PVOID winmmAlloc(DWORD cb) { PVOID ptr; ptr = (PVOID)HeapAlloc(hHeap, 0, cb); if (ptr == NULL) { return NULL; } else { ZeroMemory(ptr, cb); return ptr; } } /* * @doc INTERNAL MCI * @api PVOID | mciReAlloc | ReAllocate memory from our heap and zero extra * * @parm DWORD | cb | The new size * * @rdesc returns pointer to the new memory * */ PVOID winmmReAlloc(PVOID ptr, DWORD cb) { PVOID newptr; DWORD oldcb; newptr = (PVOID)HeapAlloc(hHeap, 0, cb); if (newptr != NULL) { oldcb = (DWORD)HeapSize(hHeap, 0, ptr); if (oldcb