/**************************************************************************** * * 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