mirror of https://github.com/tongzx/nt5src
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.
237 lines
5.5 KiB
237 lines
5.5 KiB
/****************************************************************************
|
|
*
|
|
* drvlib.c
|
|
*
|
|
* Multimedia kernel driver support library (drvlib)
|
|
*
|
|
* Copyright (c) 1993-1995 Microsoft Corporation
|
|
*
|
|
* This module contains
|
|
*
|
|
* -- the entry point and startup code
|
|
* -- debug support code
|
|
*
|
|
* History
|
|
*
|
|
***************************************************************************/
|
|
|
|
#include <drvlib.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
|
|
CRITICAL_SECTION mmDrvCritSec; // Serialize access to device lists
|
|
|
|
#if DBG
|
|
char ModuleName[MAX_PATH];
|
|
#endif
|
|
|
|
#if DBG
|
|
/*
|
|
* read profile item from registry
|
|
*/
|
|
|
|
//#include <profile.key>
|
|
#define KEYNAMEA "Software\\Microsoft\\Multimedia\\"
|
|
#define KEYNAME TEXT("Software\\Microsoft\\Multimedia\\")
|
|
#define KEYNAMEW KEYNAME
|
|
#define ROOTKEY HKEY_CURRENT_USER
|
|
|
|
UINT mmGetProfileIntA(LPCSTR appname, LPCSTR valuename, INT uDefault);
|
|
|
|
// Now map all instances of GetProfileIntA to mmGetProfileIntA
|
|
#define GetProfileIntA mmGetProfileIntA
|
|
|
|
static HKEY GetKeyA(LPCSTR appname, BOOL fCreate)
|
|
{
|
|
HKEY key = 0;
|
|
char achName[MAX_PATH];
|
|
|
|
lstrcpyA(achName, KEYNAMEA);
|
|
lstrcatA(achName, appname);
|
|
|
|
if ((!fCreate && RegOpenKeyA(ROOTKEY, achName, &key) == ERROR_SUCCESS)
|
|
|| (fCreate && RegCreateKeyA(ROOTKEY, achName, &key) == ERROR_SUCCESS)) {
|
|
}
|
|
|
|
return(key);
|
|
}
|
|
|
|
/*
|
|
* read a UINT from the profile, or return default if
|
|
* not found.
|
|
*/
|
|
UINT
|
|
mmGetProfileIntA(LPCSTR appname, LPCSTR valuename, INT uDefault)
|
|
{
|
|
DWORD dwType;
|
|
INT value = uDefault;
|
|
DWORD dwData;
|
|
int cbData;
|
|
|
|
HKEY key = GetKeyA(appname, FALSE);
|
|
|
|
if (key) {
|
|
|
|
cbData = sizeof(dwData);
|
|
if (RegQueryValueExA(
|
|
key,
|
|
(LPSTR)valuename,
|
|
NULL,
|
|
&dwType,
|
|
(PBYTE) &dwData,
|
|
&cbData) == ERROR_SUCCESS) {
|
|
if (dwType == REG_DWORD || dwType == REG_BINARY) {
|
|
value = (INT)dwData;
|
|
} else if (dwType == REG_SZ) {
|
|
value = atoi((LPSTR) &dwData);
|
|
}
|
|
}
|
|
|
|
RegCloseKey(key);
|
|
}
|
|
|
|
return((UINT)value);
|
|
}
|
|
|
|
#endif // DBG
|
|
|
|
/**************************************************************************
|
|
|
|
@doc EXTERNAL
|
|
|
|
@api BOOL | DllInstanceInit | This procedure is called whenever a
|
|
process attaches or detaches from the DLL.
|
|
|
|
@parm PVOID | hModule | Handle of the DLL.
|
|
|
|
@parm ULONG | Reason | What the reason for the call is.
|
|
|
|
@parm PCONTEXT | pContext | Some random other information.
|
|
|
|
@rdesc The return value is TRUE if the initialisation completed ok,
|
|
FALSE if not.
|
|
|
|
**************************************************************************/
|
|
|
|
BOOL DrvLibInit(HINSTANCE hModule, ULONG Reason, PCONTEXT pContext)
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER(pContext);
|
|
|
|
if (Reason == DLL_PROCESS_ATTACH) {
|
|
|
|
#if DBG
|
|
/*
|
|
** Cache our dll name for debugging
|
|
*/
|
|
|
|
{
|
|
char ModuleFileName[MAX_PATH];
|
|
|
|
if (GetModuleFileNameA((HMODULE)hModule, ModuleFileName, MAX_PATH) ==
|
|
0) {
|
|
mmdrvDebugLevel = 0;
|
|
} else {
|
|
char drive[MAX_PATH];
|
|
char dir[MAX_PATH];
|
|
char ext[MAX_PATH];
|
|
|
|
// note: we could use the WIN32 API GetFileTitle
|
|
_splitpath(ModuleFileName, drive, dir, ModuleName, ext);
|
|
mmdrvDebugLevel = GetProfileIntA("DEBUG", ModuleName, 0);
|
|
dprintf2 (("Starting, debug level=%d", mmdrvDebugLevel));
|
|
}
|
|
}
|
|
#endif
|
|
hInstance = hModule;
|
|
|
|
//
|
|
// Create our process DLL heap
|
|
//
|
|
hHeap = GetProcessHeap();
|
|
if (hHeap == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
DisableThreadLibraryCalls(hModule);
|
|
InitializeCriticalSection(&mmDrvCritSec);
|
|
|
|
//
|
|
// Load our device list
|
|
//
|
|
|
|
if (sndFindDevices() != MMSYSERR_NOERROR) {
|
|
DeleteCriticalSection(&mmDrvCritSec);
|
|
return FALSE;
|
|
}
|
|
|
|
} else {
|
|
if (Reason == DLL_PROCESS_DETACH) {
|
|
dprintf2(("Ending"));
|
|
|
|
TerminateMidi();
|
|
TerminateWave();
|
|
|
|
DeleteCriticalSection(&mmDrvCritSec);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
#if DBG
|
|
|
|
int mmdrvDebugLevel = 0;
|
|
|
|
/***************************************************************************
|
|
|
|
@doc INTERNAL
|
|
|
|
@api void | mmdrvDbgOut | This function sends output to the current
|
|
debug output device.
|
|
|
|
@parm LPSTR | lpszFormat | Pointer to a printf style format string.
|
|
@parm ??? | ... | Args.
|
|
|
|
@rdesc There is no return value.
|
|
|
|
****************************************************************************/
|
|
|
|
void mmdrvDbgOut(LPSTR lpszFormat, ...)
|
|
{
|
|
char buf[256];
|
|
va_list va;
|
|
|
|
OutputDebugStringA(ModuleName);
|
|
OutputDebugStringA(": ");
|
|
|
|
va_start(va, lpszFormat);
|
|
vsprintf(buf, lpszFormat, va);
|
|
va_end(va);
|
|
|
|
OutputDebugStringA(buf);
|
|
OutputDebugStringA("\n");
|
|
}
|
|
|
|
/***************************************************************************
|
|
|
|
@doc INTERNAL
|
|
|
|
@api void | dDbgAssert | This function prints an assertion message.
|
|
|
|
@parm LPSTR | exp | Pointer to the expression string.
|
|
@parm LPSTR | file | Pointer to the file name.
|
|
@parm int | line | The line number.
|
|
|
|
@rdesc There is no return value.
|
|
|
|
****************************************************************************/
|
|
|
|
void dDbgAssert(LPSTR exp, LPSTR file, int line)
|
|
{
|
|
dprintf1(("Assertion failure:"));
|
|
dprintf1((" Exp: %s", exp));
|
|
dprintf1((" File: %s, line: %d", file, line));
|
|
DebugBreak();
|
|
}
|
|
|
|
#endif // DBG
|