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.
 
 
 
 
 
 

205 lines
5.2 KiB

/* Copyright (c) 1998 Microsoft Corporation */
/*
* @Doc DMusic
*
* @Module DMusic16.c - Startup code |
*
* 16-bit Dll for DirectMusic sequencing on legacy devices (Win95/Win98 non-WDM drivers)
*
* This Dll is the 16-bit thunk peer for DMusic32.Dll
*
* @globalv HINSTANCE | ghInst | The instance handle for the DLL.
*
*/
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include "dmusic16.h"
#include "debug.h"
HINSTANCE ghInst;
HDRVR ghDrvr;
UINT guReferenceCount = 0;
/* @func LibMain system entry point
*
* @comm
*
* This entry point is called when the DLL is first loaded (NOT every time).
*
* Saves the global instance handle and initializes all the other modules.
*
*/
int PASCAL
LibMain(
HINSTANCE hInst, /* @parm Instance handle for the DLL */
WORD cbHeap, /* @parm Initial size of the local heap */
LPSTR lpszCmdLine) /* @parm Command-line parameters */
{
UINT uLev;
char szFilename[260];
if (GetModuleFileName(hInst, szFilename, sizeof(szFilename)))
{
DPF(2, "%s", (LPSTR)szFilename);
}
ghDrvr = OpenDriver(szFilename, NULL, 0L);
DPF(1, "DMusic16.DLL task %04X hdrvr %04X", GetCurrentTask(), (WORD)ghDrvr);
ghInst = hInst;
uLev = DbgInitialize(TRUE);
DPF(0, "DMusic16: Debug level is %u", uLev);
if (uLev > 2)
{
DPF(0, "DMusic16: Break in LibMain");
DebugBreak();
}
DeviceOnLoad();
AllocOnLoad();
MidiOutOnLoad();
#if 0
// This causes problems at terminate time. Find out later if we really need it.
//
if (!CreateTimerTask())
{
DPF(0, "CreateTimerTask() failed");
}
if (NULL == (LoadLibrary("dmusic16")))
{
DPF(0, "Could not LoadLibrary ourselves!");
}
#endif
return 1;
}
/* @func LibExit system call
*
* @comm
*
* This entry point is called just before the DLL is unloaded.
*
* Uninitialize all the other modules
*/
VOID PASCAL __loadds
LibExit(VOID)
{
DPF(2, "LibExit start");
#if 0
DestroyTimerTask();
#endif
MidiOutOnExit();
AllocOnExit();
DPF(2, "LibExit end, going away now.");
}
extern BOOL FAR PASCAL dmthunk_ThunkConnect16(LPCSTR, LPCSTR, HINSTANCE, DWORD);
STATIC char pszDll16[] = "DMUSIC16.DLL";
STATIC char pszDll32[] = "DMUSIC.DLL";
/* @func DLLEntryPoint system entry point
*
* @comm
*
* This entry point is called each time the DLL is loaded or unloaded
*
* It is used here to initialize the peer connection for the thunk layer.
*/
#define PROCESS_DETACH 0
#define PROCESS_ATTACH 1
BOOL WINAPI
DllEntryPoint(
DWORD dwReason, /* @parm Is the DLL being loaded or unloaded? */
HINSTANCE hi, /* @parm The instance handle */
HGLOBAL hgDS, /* @parm The global handle of the DLL's (shared) DS */
WORD wHeapSize, /* @parm The initial size of the local heap */
LPCSTR lszCmdLine, /* @parm The command line (always NULL) */
WORD wCmdLine) /* @parm Unused */
{
// DllEntryPoint is called before LibEntry in a 4.x dll, so we have to LocalInit here if we're
// going to use LocalAlloc
//
if (guReferenceCount == 0 && wHeapSize)
{
LocalInit(0, 0, wHeapSize);
}
switch(dwReason)
{
case PROCESS_ATTACH:
DPF(2, "ProcessAttach task %04X", GetCurrentTask());
++guReferenceCount;
dmthunk_ThunkConnect16(pszDll16, pszDll32, ghInst, 1);
break;
case PROCESS_DETACH:
DPF(2, "ProcessDetach task %04X", GetCurrentTask());
/* Clean up after them if they didn't close handles. We must do this here as well as
* in DriverProc because on the last exit, we will go away before the DriverProc cleanup
* gets called if the process termination is normal.
*/
CloseDevicesForTask(GetCurrentTask());
/* NOTE: We close on reference count of 1 since the initial OpenDriver call
causes one more PROCESS_ATTACH to happen. */
if (1 == --guReferenceCount)
{
CloseDriver(ghDrvr, 0, 0);
}
break;
}
return TRUE;
}
/* @func DriverProc entry point for ourselves as a loadable driver.
*
* @comm This entry points allows us to know when a task has gone away and therefore to clean
* up after it even though we don't properly get notified that our thunk peer has gone away.
*/
LRESULT WINAPI DriverProc(
DWORD dwID,
HDRVR hdrvr,
UINT umsg,
LPARAM lParam1,
LPARAM lParam2)
{
//
// NOTE DS is not valid here.
//
switch (umsg)
{
case DRV_LOAD:
return(1L);
case DRV_FREE:
return(0L);
case DRV_OPEN:
case DRV_CLOSE:
return(1L);
case DRV_EXITAPPLICATION:
DPF(2, "Cleaning up handles for task %04X", GetCurrentTask());
CloseDevicesForTask(GetCurrentTask());
break;
default:
return(DefDriverProc(dwID, hdrvr, umsg, lParam1, lParam2));
}
} //** DriverProc()