reactos/dll/win32/mmdrv/session.c

249 lines
6 KiB
C
Raw Normal View History

/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Multimedia
* FILE: dll/win32/mmdrv/session.c
* PURPOSE: Multimedia User Mode Driver (session management)
* PROGRAMMER: Andrew Greenwood
* UPDATE HISTORY:
* Jan 14, 2007: Created
*/
#include "mmdrv.h"
#define NDEBUG
#include <debug.h>
/* Each session is tracked, but the list must be locked when in use */
SessionInfo* session_list = NULL;
CRITICAL_SECTION session_lock;
/*
Obtains a pointer to the session associated with a device type and ID.
If no session exists, returns NULL. This is mainly used to see if a
session already exists prior to creating a new one.
*/
SessionInfo*
GetSession(
DeviceType device_type,
Merge from amd64 branch: [SPIDER] 44002 Fix 64 bit build. (Samuel Serapión) [PAINT] 43858 Fix 64 bit warnings. (Samuel Serapión) [RAPPS] 43906 Fix 64 bit build. (Samuel Serapión) [SNDREC32] 44389 Fix 64 bit build. (Samuel Serapión) [TFTP] 41097 Fix pointer to DWORD cast. (Timo Kreuzer) [COMCTL32] 36172 Build as unicode. (Samuel Serapión) [USERMGR] 41098 Fix 2 POINTER<->DWORD casts. (Timo Kreuzer) [d3d9] 38149 Fix pointer<->ULONG cast. (Timo Kreuzer) 43839 Fix 64 bit Build. (Samuel Serapión) [DSOUND] 40753 Make DSDRIVERDESC.dnDevNode a DWORD_PTR and DSPROPERTY.InstanceId a ULONG_PTR. (Timo Kreuzer) [LSASRV] 44037 Fix 64 bit Build. (Samuel Serapión) [MMDRV] 40125 Fix 64bit build. (Samuel Serapión) [MSGINA] 40993 fix 64bit build (Timo Kreuzer) [NETSHELL] 41001 Don't cast the 1st parameter of InterlockedExchange to volatile void **, but to void ** (Timo Kreuzer) [OPENGL32] 36502 No need to assert an offset thats only used in i386 specific code. (Samuel Serapión) [POWRPROF] 41044 Don't cast NULL to DWORD. (Timo Kreuzer) 43860 Don't cast NULL to an integer type. (Samuel Serapión) [PSAPI] 38150 Fix a cast (Timo Kreuzer) [SHELL32] 38355 Use Get/SetWindowLongPtr (Samuel Serapión) 41047 Get rid of deprecated LargeInteger functions and use native int64 math instead. (Timo Kreuzer) 41048 DialogProc returns INT_PTR and not BOOL. Don't cast a pointer to LONG. Use INT_PTR instead of int for pointer math. (Timo Kreuzer) 41049 Change return type of OpenMRUListW and CreateMRUListW to HANDLE, add a comment that CREATEMRULISTW is already defined differently in explorer_new/undoc.h (Timo Kreuzer) 44601 Fix a prototype. Convert RtlLargeInteger to native int64. Fixes 64bit built. (Timo Kreuzer) [WDMAUD.DRV] 41101 Don't cast DWORD to PVOID, use UlongToPtr instead. (Timo Kreuzer) [WS2_32] 35777 fix ws2_32 spec file (Timo kreuzer) 44044 Fix ws2_32 64bit build (1 of 2) (Samuel Serapión) 44045 Fix ws2_32 64bit build (2 of 2) (Samuel Serapión) [WS2_32_NEW] 44389 Fix 64 bit built. (Samuel Serapión) svn path=/trunk/; revision=44602
2009-12-15 15:16:01 +00:00
UINT device_id)
{
SessionInfo* session_info;
EnterCriticalSection(&session_lock);
session_info = session_list;
while ( session_info )
{
if ( ( session_info->device_type == device_type ) &&
( session_info->device_id == device_id ) )
{
LeaveCriticalSection(&session_lock);
return session_info;
}
session_info = session_info->next;
}
LeaveCriticalSection(&session_lock);
return NULL;
}
/*
Creates a new session, associated with the specified device type and ID.
Whilst the session list is locked, this also checks to see if an existing
session is associated with the device.
*/
MMRESULT
CreateSession(
DeviceType device_type,
Merge from amd64 branch: [SPIDER] 44002 Fix 64 bit build. (Samuel Serapión) [PAINT] 43858 Fix 64 bit warnings. (Samuel Serapión) [RAPPS] 43906 Fix 64 bit build. (Samuel Serapión) [SNDREC32] 44389 Fix 64 bit build. (Samuel Serapión) [TFTP] 41097 Fix pointer to DWORD cast. (Timo Kreuzer) [COMCTL32] 36172 Build as unicode. (Samuel Serapión) [USERMGR] 41098 Fix 2 POINTER<->DWORD casts. (Timo Kreuzer) [d3d9] 38149 Fix pointer<->ULONG cast. (Timo Kreuzer) 43839 Fix 64 bit Build. (Samuel Serapión) [DSOUND] 40753 Make DSDRIVERDESC.dnDevNode a DWORD_PTR and DSPROPERTY.InstanceId a ULONG_PTR. (Timo Kreuzer) [LSASRV] 44037 Fix 64 bit Build. (Samuel Serapión) [MMDRV] 40125 Fix 64bit build. (Samuel Serapión) [MSGINA] 40993 fix 64bit build (Timo Kreuzer) [NETSHELL] 41001 Don't cast the 1st parameter of InterlockedExchange to volatile void **, but to void ** (Timo Kreuzer) [OPENGL32] 36502 No need to assert an offset thats only used in i386 specific code. (Samuel Serapión) [POWRPROF] 41044 Don't cast NULL to DWORD. (Timo Kreuzer) 43860 Don't cast NULL to an integer type. (Samuel Serapión) [PSAPI] 38150 Fix a cast (Timo Kreuzer) [SHELL32] 38355 Use Get/SetWindowLongPtr (Samuel Serapión) 41047 Get rid of deprecated LargeInteger functions and use native int64 math instead. (Timo Kreuzer) 41048 DialogProc returns INT_PTR and not BOOL. Don't cast a pointer to LONG. Use INT_PTR instead of int for pointer math. (Timo Kreuzer) 41049 Change return type of OpenMRUListW and CreateMRUListW to HANDLE, add a comment that CREATEMRULISTW is already defined differently in explorer_new/undoc.h (Timo Kreuzer) 44601 Fix a prototype. Convert RtlLargeInteger to native int64. Fixes 64bit built. (Timo Kreuzer) [WDMAUD.DRV] 41101 Don't cast DWORD to PVOID, use UlongToPtr instead. (Timo Kreuzer) [WS2_32] 35777 fix ws2_32 spec file (Timo kreuzer) 44044 Fix ws2_32 64bit build (1 of 2) (Samuel Serapión) 44045 Fix ws2_32 64bit build (2 of 2) (Samuel Serapión) [WS2_32_NEW] 44389 Fix 64 bit built. (Samuel Serapión) svn path=/trunk/; revision=44602
2009-12-15 15:16:01 +00:00
UINT device_id,
SessionInfo** session_info)
{
HANDLE heap = GetProcessHeap();
ASSERT(session_info);
EnterCriticalSection(&session_lock);
/* Ensure we're not creating a duplicate session */
if ( GetSession(device_type, device_id) )
{
DPRINT("Already allocated session\n");
LeaveCriticalSection(&session_lock);
return MMSYSERR_ALLOCATED;
}
*session_info = HeapAlloc(heap, HEAP_ZERO_MEMORY, sizeof(SessionInfo));
if ( ! *session_info )
{
DPRINT("Failed to allocate mem for session info\n");
LeaveCriticalSection(&session_lock);
return MMSYSERR_NOMEM;
}
(*session_info)->device_type = device_type;
(*session_info)->device_id = device_id;
/* Add to the list */
(*session_info)->next = session_list;
session_list = *session_info;
LeaveCriticalSection(&session_lock);
return MMSYSERR_NOERROR;
}
/*
Removes a session from the list and destroys it. This function does NOT
perform any additional cleanup. Think of it as a slightly more advanced
free()
*/
VOID
DestroySession(SessionInfo* session)
{
HANDLE heap = GetProcessHeap();
SessionInfo* session_node;
SessionInfo* session_prev;
/* TODO: More cleanup stuff */
/* Remove from the list */
EnterCriticalSection(&session_lock);
session_node = session_list;
session_prev = NULL;
while ( session_node )
{
if ( session_node == session )
{
/* Bridge the gap for when we go */
session_prev->next = session->next;
break;
}
/* Save the previous node, fetch the next */
session_prev = session_node;
session_node = session_node->next;
}
LeaveCriticalSection(&session_lock);
HeapFree(heap, 0, session);
}
/*
Allocates events and other resources for the session thread, starts it,
and waits for it to announce that it is ready to work for us.
*/
MMRESULT
StartSessionThread(SessionInfo* session_info)
{
LPTASKCALLBACK task;
MMRESULT result;
ASSERT(session_info);
/* This is our "ready" event, sent when the thread is idle */
session_info->thread.ready_event = CreateEvent(NULL, FALSE, FALSE, NULL);
if ( ! session_info->thread.ready_event )
{
DPRINT("Couldn't create thread_ready event\n");
return MMSYSERR_NOMEM;
}
/* This is our "go" event, sent when we want the thread to do something */
session_info->thread.go_event = CreateEvent(NULL, FALSE, FALSE, NULL);
if ( ! session_info->thread.go_event )
{
DPRINT("Couldn't create thread_go event\n");
CloseHandle(session_info->thread.ready_event);
return MMSYSERR_NOMEM;
}
/* TODO - other kinds of devices need attention, too */
task = ( session_info->device_type == WaveOutDevice )
? (LPTASKCALLBACK) WaveThread : NULL;
ASSERT(task);
/* Effectively, this is a beefed-up CreateThread */
result = mmTaskCreate(task,
&session_info->thread.handle,
Merge from amd64 branch: [SPIDER] 44002 Fix 64 bit build. (Samuel Serapión) [PAINT] 43858 Fix 64 bit warnings. (Samuel Serapión) [RAPPS] 43906 Fix 64 bit build. (Samuel Serapión) [SNDREC32] 44389 Fix 64 bit build. (Samuel Serapión) [TFTP] 41097 Fix pointer to DWORD cast. (Timo Kreuzer) [COMCTL32] 36172 Build as unicode. (Samuel Serapión) [USERMGR] 41098 Fix 2 POINTER<->DWORD casts. (Timo Kreuzer) [d3d9] 38149 Fix pointer<->ULONG cast. (Timo Kreuzer) 43839 Fix 64 bit Build. (Samuel Serapión) [DSOUND] 40753 Make DSDRIVERDESC.dnDevNode a DWORD_PTR and DSPROPERTY.InstanceId a ULONG_PTR. (Timo Kreuzer) [LSASRV] 44037 Fix 64 bit Build. (Samuel Serapión) [MMDRV] 40125 Fix 64bit build. (Samuel Serapión) [MSGINA] 40993 fix 64bit build (Timo Kreuzer) [NETSHELL] 41001 Don't cast the 1st parameter of InterlockedExchange to volatile void **, but to void ** (Timo Kreuzer) [OPENGL32] 36502 No need to assert an offset thats only used in i386 specific code. (Samuel Serapión) [POWRPROF] 41044 Don't cast NULL to DWORD. (Timo Kreuzer) 43860 Don't cast NULL to an integer type. (Samuel Serapión) [PSAPI] 38150 Fix a cast (Timo Kreuzer) [SHELL32] 38355 Use Get/SetWindowLongPtr (Samuel Serapión) 41047 Get rid of deprecated LargeInteger functions and use native int64 math instead. (Timo Kreuzer) 41048 DialogProc returns INT_PTR and not BOOL. Don't cast a pointer to LONG. Use INT_PTR instead of int for pointer math. (Timo Kreuzer) 41049 Change return type of OpenMRUListW and CreateMRUListW to HANDLE, add a comment that CREATEMRULISTW is already defined differently in explorer_new/undoc.h (Timo Kreuzer) 44601 Fix a prototype. Convert RtlLargeInteger to native int64. Fixes 64bit built. (Timo Kreuzer) [WDMAUD.DRV] 41101 Don't cast DWORD to PVOID, use UlongToPtr instead. (Timo Kreuzer) [WS2_32] 35777 fix ws2_32 spec file (Timo kreuzer) 44044 Fix ws2_32 64bit build (1 of 2) (Samuel Serapión) 44045 Fix ws2_32 64bit build (2 of 2) (Samuel Serapión) [WS2_32_NEW] 44389 Fix 64 bit built. (Samuel Serapión) svn path=/trunk/; revision=44602
2009-12-15 15:16:01 +00:00
(DWORD_PTR)session_info);
if ( result != MMSYSERR_NOERROR )
{
DPRINT("Task creation failed\n");
CloseHandle(session_info->thread.ready_event);
CloseHandle(session_info->thread.go_event);
return result;
}
/* Wait for the thread to be ready before completing */
WaitForSingleObject(session_info->thread.ready_event, INFINITE);
return MMSYSERR_NOERROR;
}
/*
The session thread is pretty simple. Upon creation, it announces that it
is ready to do stuff for us. When we want it to perform an action, we use
CallSessionThread with an appropriate function and parameter, then tell
the thread we want it to do something. When it's finished, it announces
that it is ready once again.
*/
MMRESULT
CallSessionThread(
SessionInfo* session_info,
ThreadFunction function,
PVOID thread_parameter)
{
ASSERT(session_info);
session_info->thread.function = function;
session_info->thread.parameter = thread_parameter;
DPRINT("Calling session thread\n");
SetEvent(session_info->thread.go_event);
DPRINT("Waiting for thread response\n");
WaitForSingleObject(session_info->thread.ready_event, INFINITE);
return session_info->thread.result;
}
DWORD
HandleBySessionThread(
Merge from amd64 branch: [SPIDER] 44002 Fix 64 bit build. (Samuel Serapión) [PAINT] 43858 Fix 64 bit warnings. (Samuel Serapión) [RAPPS] 43906 Fix 64 bit build. (Samuel Serapión) [SNDREC32] 44389 Fix 64 bit build. (Samuel Serapión) [TFTP] 41097 Fix pointer to DWORD cast. (Timo Kreuzer) [COMCTL32] 36172 Build as unicode. (Samuel Serapión) [USERMGR] 41098 Fix 2 POINTER<->DWORD casts. (Timo Kreuzer) [d3d9] 38149 Fix pointer<->ULONG cast. (Timo Kreuzer) 43839 Fix 64 bit Build. (Samuel Serapión) [DSOUND] 40753 Make DSDRIVERDESC.dnDevNode a DWORD_PTR and DSPROPERTY.InstanceId a ULONG_PTR. (Timo Kreuzer) [LSASRV] 44037 Fix 64 bit Build. (Samuel Serapión) [MMDRV] 40125 Fix 64bit build. (Samuel Serapión) [MSGINA] 40993 fix 64bit build (Timo Kreuzer) [NETSHELL] 41001 Don't cast the 1st parameter of InterlockedExchange to volatile void **, but to void ** (Timo Kreuzer) [OPENGL32] 36502 No need to assert an offset thats only used in i386 specific code. (Samuel Serapión) [POWRPROF] 41044 Don't cast NULL to DWORD. (Timo Kreuzer) 43860 Don't cast NULL to an integer type. (Samuel Serapión) [PSAPI] 38150 Fix a cast (Timo Kreuzer) [SHELL32] 38355 Use Get/SetWindowLongPtr (Samuel Serapión) 41047 Get rid of deprecated LargeInteger functions and use native int64 math instead. (Timo Kreuzer) 41048 DialogProc returns INT_PTR and not BOOL. Don't cast a pointer to LONG. Use INT_PTR instead of int for pointer math. (Timo Kreuzer) 41049 Change return type of OpenMRUListW and CreateMRUListW to HANDLE, add a comment that CREATEMRULISTW is already defined differently in explorer_new/undoc.h (Timo Kreuzer) 44601 Fix a prototype. Convert RtlLargeInteger to native int64. Fixes 64bit built. (Timo Kreuzer) [WDMAUD.DRV] 41101 Don't cast DWORD to PVOID, use UlongToPtr instead. (Timo Kreuzer) [WS2_32] 35777 fix ws2_32 spec file (Timo kreuzer) 44044 Fix ws2_32 64bit build (1 of 2) (Samuel Serapión) 44045 Fix ws2_32 64bit build (2 of 2) (Samuel Serapión) [WS2_32_NEW] 44389 Fix 64 bit built. (Samuel Serapión) svn path=/trunk/; revision=44602
2009-12-15 15:16:01 +00:00
DWORD_PTR private_handle,
DWORD_PTR message,
DWORD_PTR parameter)
{
return CallSessionThread((SessionInfo*) private_handle,
message,
(PVOID) parameter);
}