/****************************************************************************** Copyright (C) Microsoft Corporation 1985-1991. All rights reserved. Title: drvproc.c - Multimedia Systems Media Control Interface driver for AVI. *****************************************************************************/ #include #include #include // 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