windows-nt/Source/XPSP1/NT/multimedia/media/avi/mciavi32/drvproc.c
2020-09-26 16:20:57 +08:00

271 lines
8.1 KiB
C

/******************************************************************************
Copyright (C) Microsoft Corporation 1985-1991. All rights reserved.
Title: drvproc.c - Multimedia Systems Media Control Interface
driver for AVI.
*****************************************************************************/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h> // for {struct _TEB} defintion
#include "graphic.h"
#include "cnfgdlg.h" // to get IDA_CONFIG
#include "avitask.h" // to get mciaviTaskCleanup()
#ifndef _WIN32 // Not used in 32 bit world
void NEAR PASCAL AppExit(HTASK htask, BOOL fNormalExit);
#endif
#define CONFIG_ID 10000L // Use the hiword of dwDriverID to identify
HANDLE ghModule;
extern HWND ghwndConfig;
extern const TCHAR szIni[];
/* Link to DefDriverProc in MMSystem explicitly, so we don't get the
** one in USER by mistake.
*/
#ifndef _WIN32
extern DWORD FAR PASCAL mmDefDriverProc(DWORD, HANDLE, UINT, DWORD, DWORD);
#else
#define mmDefDriverProc DefDriverProc
#endif
#ifndef _WIN32
BOOL FAR PASCAL LibMain (HANDLE hModule, int cbHeap, LPSTR lpchCmdLine)
{
ghModule = hModule;
return TRUE;
}
#else
#if 0
// Get the module handle on DRV_LOAD
BOOL DllInstanceInit(PVOID hModule, ULONG Reason, PCONTEXT pContext)
{
if (Reason == DLL_PROCESS_ATTACH) {
ghModule = hModule; // All we need to save is our module handle...
} else {
if (Reason == DLL_PROCESS_DETACH) {
}
}
return TRUE;
}
#endif
#endif // WIN16
/***************************************************************************
*
* @doc INTERNAL
*
* @api DWORD | DriverProc | The entry point for an installable driver.
*
* @parm DWORD | dwDriverId | For most messages, dwDriverId is the DWORD
* value that the driver returns in response to a DRV_OPEN message.
* Each time that the driver is opened, through the DrvOpen API,
* the driver receives a DRV_OPEN message and can return an
* arbitrary, non-zero, value. The installable driver interface
* saves this value and returns a unique driver handle to the
* application. Whenever the application sends a message to the
* driver using the driver handle, the interface routes the message
* to this entry point and passes the corresponding dwDriverId.
*
* This mechanism allows the driver to use the same or different
* identifiers for multiple opens but ensures that driver handles
* are unique at the application interface layer.
*
* The following messages are not related to a particular open
* instance of the driver. For these messages, the dwDriverId
* will always be ZERO.
*
* DRV_LOAD, DRV_FREE, DRV_ENABLE, DRV_DISABLE, DRV_OPEN
*
* @parm UINT | wMessage | The requested action to be performed. Message
* values below DRV_RESERVED are used for globally defined messages.
* Message values from DRV_RESERVED to DRV_USER are used for
* defined driver portocols. Messages above DRV_USER are used
* for driver specific messages.
*
* @parm DWORD | dwParam1 | Data for this message. Defined separately for
* each message
*
* @parm DWORD | dwParam2 | Data for this message. Defined separately for
* each message
*
* @rdesc Defined separately for each message.
*
***************************************************************************/
LRESULT FAR PASCAL _LOADDS DriverProc (DWORD_PTR dwDriverID, HANDLE hDriver, UINT wMessage,
LPARAM dwParam1, LPARAM dwParam2)
{
DWORD_PTR dwRes = 0L;
/*
* critical sections are now per-device. This means they
* cannot be held around the whole driver-proc, since until we open
* the device, we don't have a critical section to hold.
* The critical section is allocated in mciSpecial on opening. It is
* also held in mciDriverEntry, in GraphicWndProc, and around
* all worker thread draw functions.
*/
switch (wMessage)
{
// Standard, globally used messages.
case DRV_LOAD:
{
struct _TEB *pteb;
BOOL bWow64;
#ifdef _WIN32
if (ghModule) {
Assert(!"Did not expect ghModule to be non-NULL");
}
ghModule = GetDriverModuleHandle(hDriver); // Remember
// The WOW guys say that the proper method of detecting
// whether we're talking to a 16-bit app is to test
// NtCurrentTeb()->WOW32Reserved; if it's nonzero, it's 16-bit.
// In the (unlikely) event that we can't test that, default
// to using the old detection method.
// On 64-bit systems WOW32Reserved is used for something else.
//
if (!IsWow64Process(GetCurrentProcess(), &bWow64)) {
break;
}
if (!bWow64) {
if ((pteb = NtCurrentTeb()) != NULL) {
runningInWow = (pteb->WOW32Reserved != 0) ? TRUE : FALSE;
} else {
#define GET_MAPPING_MODULE_NAME TEXT("wow32.dll")
runningInWow = (GetModuleHandle(GET_MAPPING_MODULE_NAME) != NULL);
}
}
#endif
if (GraphicInit()) // Initialize graphic mgmt.
dwRes = 1L;
else
dwRes = 0L;
break;
}
case DRV_FREE:
GraphicFree();
dwRes = 1L;
DPF(("Returning from DRV_FREE\n"));
Assert(npMCIList == NULL);
ghModule = NULL;
break;
case DRV_OPEN:
if (!dwParam2)
dwRes = CONFIG_ID;
else
dwRes = GraphicDrvOpen((LPMCI_OPEN_DRIVER_PARMS)dwParam2);
break;
case DRV_CLOSE:
/* If we have a configure dialog up, fail the close.
** Otherwise, we'll be unloaded while we still have the
** configuration window up.
*/
if (ghwndConfig)
dwRes = 0L;
else
dwRes = 1L;
break;
case DRV_ENABLE:
dwRes = 1L;
break;
case DRV_DISABLE:
dwRes = 1L;
break;
case DRV_QUERYCONFIGURE:
dwRes = 1L; /* Yes, we can be configured */
break;
case DRV_CONFIGURE:
ConfigDialog((HWND)(UINT)dwParam1, NULL);
dwRes = 1L;
break;
#ifndef _WIN32
//
// sent when a application is terminating
//
// lParam1:
// DRVEA_ABNORMALEXIT
// DRVEA_NORMALEXIT
//
case DRV_EXITAPPLICATION:
AppExit(GetCurrentTask(), (BOOL)dwParam1 == DRVEA_NORMALEXIT);
break;
#endif
default:
if (!HIWORD(dwDriverID) &&
wMessage >= DRV_MCI_FIRST &&
wMessage <= DRV_MCI_LAST)
dwRes = mciDriverEntry ((UINT) (UINT_PTR) dwDriverID,
wMessage,
(UINT) dwParam1,
(LPMCI_GENERIC_PARMS)dwParam2);
else
dwRes = mmDefDriverProc(dwDriverID,
hDriver,
wMessage,
dwParam1,
dwParam2);
break;
}
return dwRes;
}
#ifndef _WIN32
/*****************************************************************************
* @doc INTERNAL
*
* @func void | AppExit |
* a application is exiting
*
****************************************************************************/
void NEAR PASCAL AppExit(HTASK htask, BOOL fNormalExit)
{
//
// walk the list of open MCIAVI instances and see if
// the dying task is the background task and do cleanup.
//
NPMCIGRAPHIC npMCI;
// Note: we do not have EnterList/LeaveList macros here as this is
// explicitly NOT Win32 code.
for (npMCI=npMCIList; npMCI; npMCI = npMCI->npMCINext) {
if (npMCI->hTask == htask) {
DPF(("Calling mciaviTaskCleanup()\n"));
mciaviTaskCleanup(npMCI);
return;
}
}
}
#endif