271 lines
8.1 KiB
C
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
|