windows-nt/Source/XPSP1/NT/multimedia/media/winmm/util.c

289 lines
8.1 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/****************************************************************************
*
* 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 <p wFlags> 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 <p dwCallback>
* 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
* <p dwCallback> 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, <p hDevice>,
* <p wMsg>, <p dwUser>, <p dwParam1>, and <p dwParam2> are passed to
* the callback. If notification is done with a window, only <p wMsg>,
* <p hDevice>, and <p dwParam1> 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<cb) { // Block is being expanded
ZeroMemory((PBYTE)newptr+oldcb, cb-oldcb);
cb = oldcb;
}
CopyMemory(newptr, ptr, cb);
HeapFree(hHeap, 0, ptr);
}
return newptr;
}