From 7643df49d7564a74438a1e3050779793aaacaff5 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Wed, 4 Jan 2006 14:49:34 +0100 Subject: [PATCH] dsound: Capture cleanup. Move code and function prototypes around to eliminate forward declarations. No code is changed. --- dlls/dsound/capture.c | 498 +++++++++++++++++++++---------------------- dlls/dsound/dsound_private.h | 25 ++- 2 files changed, 263 insertions(+), 260 deletions(-) diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c index b2633f26613..e91d618befb 100644 --- a/dlls/dsound/capture.c +++ b/dlls/dsound/capture.c @@ -44,18 +44,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dsound); -static HRESULT WINAPI IDirectSoundCaptureImpl_Initialize( - LPDIRECTSOUNDCAPTURE iface, - LPCGUID lpcGUID ); -static ULONG WINAPI IDirectSoundCaptureImpl_Release( - LPDIRECTSOUNDCAPTURE iface ); -static ULONG WINAPI IDirectSoundCaptureBufferImpl_Release( - LPDIRECTSOUNDCAPTUREBUFFER8 iface ); -static HRESULT DSOUND_CreateDirectSoundCaptureBuffer( - IDirectSoundCaptureImpl *ipDSC, - LPCDSCBUFFERDESC lpcDSCBufferDesc, - LPVOID* ppobj ); - static const IDirectSoundCaptureVtbl dscvt; static const IDirectSoundCaptureBuffer8Vtbl dscbvt; @@ -68,30 +56,7 @@ static const char * captureStateString[] = { "STATE_STOPPING" }; -HRESULT IDirectSoundCaptureImpl_Create( - LPDIRECTSOUNDCAPTURE8 * ppDSC) -{ - IDirectSoundCaptureImpl *pDSC; - TRACE("(%p)\n", ppDSC); - - /* Allocate memory */ - pDSC = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundCaptureImpl)); - if (pDSC == NULL) { - WARN("out of memory\n"); - *ppDSC = NULL; - return DSERR_OUTOFMEMORY; - } - - pDSC->lpVtbl = &dscvt; - pDSC->ref = 0; - pDSC->device = NULL; - - *ppDSC = (LPDIRECTSOUNDCAPTURE8)pDSC; - - return DS_OK; -} - -HRESULT DSOUND_CaptureCreate( +static HRESULT DSOUND_CaptureCreate( LPDIRECTSOUNDCAPTURE *ppDSC, IUnknown *pUnkOuter) { @@ -114,7 +79,7 @@ HRESULT DSOUND_CaptureCreate( return hr; } -HRESULT DSOUND_CaptureCreate8( +static HRESULT DSOUND_CaptureCreate8( LPDIRECTSOUNDCAPTURE8 *ppDSC8, IUnknown *pUnkOuter) { @@ -249,31 +214,6 @@ HRESULT WINAPI DirectSoundCaptureCreate8( return hr; } -static HRESULT DirectSoundCaptureDevice_Create( - DirectSoundCaptureDevice ** ppDevice) -{ - DirectSoundCaptureDevice * device; - TRACE("(%p)\n", ppDevice); - - /* Allocate memory */ - device = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DirectSoundCaptureDevice)); - - if (device == NULL) { - WARN("out of memory\n"); - return DSERR_OUTOFMEMORY; - } - - device->ref = 1; - device->state = STATE_STOPPED; - - InitializeCriticalSection( &(device->lock) ); - device->lock.DebugInfo->Spare[0] = (DWORD_PTR)"DSCAPTURE_lock"; - - *ppDevice = device; - - return DS_OK; -} - /*************************************************************************** * DirectSoundCaptureEnumerateA [DSOUND.7] * @@ -451,6 +391,9 @@ DSOUND_capture_callback( TRACE("completed\n"); } +/*************************************************************************** + * IDirectSoundCaptureImpl + */ static HRESULT WINAPI IDirectSoundCaptureImpl_QueryInterface( LPDIRECTSOUNDCAPTURE iface, @@ -490,35 +433,6 @@ IDirectSoundCaptureImpl_AddRef( LPDIRECTSOUNDCAPTURE iface ) return ref; } -static ULONG DirectSoundCaptureDevice_Release( - DirectSoundCaptureDevice * device) -{ - ULONG ref; - TRACE("(%p) ref was %lu\n", device, device->ref); - - device->ref--; - ref=device->ref; - if (device->ref == 0) { - TRACE("deleting object\n"); - if (device->capture_buffer) - IDirectSoundCaptureBufferImpl_Release( - (LPDIRECTSOUNDCAPTUREBUFFER8) device->capture_buffer); - - if (device->driver) { - IDsCaptureDriver_Close(device->driver); - IDsCaptureDriver_Release(device->driver); - } - - HeapFree(GetProcessHeap(), 0, device->pwfx); - device->lock.DebugInfo->Spare[0] = 0; - DeleteCriticalSection( &(device->lock) ); - DSOUND_capture[device->drvdesc.dnDevNode] = NULL; - HeapFree(GetProcessHeap(), 0, device); - TRACE("(%p) released\n", device); - } - return ref; -} - static ULONG WINAPI IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface ) { @@ -757,173 +671,26 @@ static const IDirectSoundCaptureVtbl dscvt = IDirectSoundCaptureImpl_Initialize }; -static HRESULT -DSOUND_CreateDirectSoundCaptureBuffer( - IDirectSoundCaptureImpl *ipDSC, - LPCDSCBUFFERDESC lpcDSCBufferDesc, - LPVOID* ppobj ) +HRESULT IDirectSoundCaptureImpl_Create( + LPDIRECTSOUNDCAPTURE8 * ppDSC) { - LPWAVEFORMATEX wfex; - TRACE( "(%p,%p)\n", lpcDSCBufferDesc, ppobj ); - - if (ipDSC == NULL) { - WARN("invalid parameter: ipDSC == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (lpcDSCBufferDesc == NULL) { - WARN("invalid parameter: lpcDSCBufferDesc == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if (ppobj == NULL) { - WARN("invalid parameter: ppobj == NULL\n"); - return DSERR_INVALIDPARAM; - } - - if ( ((lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC)) && - (lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC1))) || - (lpcDSCBufferDesc->dwBufferBytes == 0) || - (lpcDSCBufferDesc->lpwfxFormat == NULL) ) { - WARN("invalid lpcDSCBufferDesc\n"); - *ppobj = NULL; - return DSERR_INVALIDPARAM; - } - - if ( !ipDSC->device) { - WARN("not initialized\n"); - *ppobj = NULL; - return DSERR_UNINITIALIZED; - } - - wfex = lpcDSCBufferDesc->lpwfxFormat; - - if (wfex) { - TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld," - "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n", - wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec, - wfex->nAvgBytesPerSec, wfex->nBlockAlign, - wfex->wBitsPerSample, wfex->cbSize); + IDirectSoundCaptureImpl *pDSC; + TRACE("(%p)\n", ppDSC); - if (wfex->wFormatTag == WAVE_FORMAT_PCM) { - ipDSC->device->pwfx = HeapAlloc(GetProcessHeap(),0,sizeof(WAVEFORMATEX)); - CopyMemory(ipDSC->device->pwfx, wfex, sizeof(WAVEFORMATEX)); - ipDSC->device->pwfx->cbSize = 0; - } else { - ipDSC->device->pwfx = HeapAlloc(GetProcessHeap(),0,sizeof(WAVEFORMATEX)+wfex->cbSize); - CopyMemory(ipDSC->device->pwfx, wfex, sizeof(WAVEFORMATEX)+wfex->cbSize); - } - } else { - WARN("lpcDSCBufferDesc->lpwfxFormat == 0\n"); - *ppobj = NULL; - return DSERR_INVALIDPARAM; /* FIXME: DSERR_BADFORMAT ? */ + /* Allocate memory */ + pDSC = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundCaptureImpl)); + if (pDSC == NULL) { + WARN("out of memory\n"); + *ppDSC = NULL; + return DSERR_OUTOFMEMORY; } - *ppobj = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, - sizeof(IDirectSoundCaptureBufferImpl)); - - if ( *ppobj == NULL ) { - WARN("out of memory\n"); - *ppobj = NULL; - return DSERR_OUTOFMEMORY; - } else { - HRESULT err = DS_OK; - LPBYTE newbuf; - DWORD buflen; - IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)*ppobj; - - This->ref = 1; - This->dsound = ipDSC; - This->dsound->device->capture_buffer = This; - This->notify = NULL; - This->nrofnotifies = 0; - This->hwnotify = NULL; - - This->pdscbd = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, - lpcDSCBufferDesc->dwSize); - if (This->pdscbd) - CopyMemory(This->pdscbd, lpcDSCBufferDesc, lpcDSCBufferDesc->dwSize); - else { - WARN("no memory\n"); - This->dsound->device->capture_buffer = 0; - HeapFree( GetProcessHeap(), 0, This ); - *ppobj = NULL; - return DSERR_OUTOFMEMORY; - } - - This->lpVtbl = &dscbvt; - - if (ipDSC->device->driver) { - if (This->dsound->device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) - FIXME("DSDDESC_DOMMSYSTEMOPEN not supported\n"); - - if (This->dsound->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) { - /* allocate buffer from system memory */ - buflen = lpcDSCBufferDesc->dwBufferBytes; - TRACE("desired buflen=%ld, old buffer=%p\n", buflen, ipDSC->device->buffer); - if (ipDSC->device->buffer) - newbuf = HeapReAlloc(GetProcessHeap(),0,ipDSC->device->buffer,buflen); - else - newbuf = HeapAlloc(GetProcessHeap(),0,buflen); - - if (newbuf == NULL) { - WARN("failed to allocate capture buffer\n"); - err = DSERR_OUTOFMEMORY; - /* but the old buffer might still exist and must be re-prepared */ - } else { - ipDSC->device->buffer = newbuf; - ipDSC->device->buflen = buflen; - } - } else { - /* let driver allocate memory */ - ipDSC->device->buflen = lpcDSCBufferDesc->dwBufferBytes; - /* FIXME: */ - HeapFree( GetProcessHeap(), 0, ipDSC->device->buffer); - ipDSC->device->buffer = NULL; - } - - err = IDsCaptureDriver_CreateCaptureBuffer(ipDSC->device->driver, - ipDSC->device->pwfx,0,0,&(ipDSC->device->buflen),&(ipDSC->device->buffer),(LPVOID*)&(ipDSC->device->hwbuf)); - if (err != DS_OK) { - WARN("IDsCaptureDriver_CreateCaptureBuffer failed\n"); - This->dsound->device->capture_buffer = 0; - HeapFree( GetProcessHeap(), 0, This ); - *ppobj = NULL; - return err; - } - } else { - DWORD flags = CALLBACK_FUNCTION; - if (ds_hw_accel != DS_HW_ACCEL_EMULATION) - flags |= WAVE_DIRECTSOUND; - err = mmErr(waveInOpen(&(ipDSC->device->hwi), - ipDSC->device->drvdesc.dnDevNode, ipDSC->device->pwfx, - (DWORD_PTR)DSOUND_capture_callback, (DWORD)ipDSC->device, flags)); - if (err != DS_OK) { - WARN("waveInOpen failed\n"); - This->dsound->device->capture_buffer = 0; - HeapFree( GetProcessHeap(), 0, This ); - *ppobj = NULL; - return err; - } + pDSC->lpVtbl = &dscvt; + pDSC->ref = 0; + pDSC->device = NULL; - buflen = lpcDSCBufferDesc->dwBufferBytes; - TRACE("desired buflen=%ld, old buffer=%p\n", buflen, ipDSC->device->buffer); - if (ipDSC->device->buffer) - newbuf = HeapReAlloc(GetProcessHeap(),0,ipDSC->device->buffer,buflen); - else - newbuf = HeapAlloc(GetProcessHeap(),0,buflen); - if (newbuf == NULL) { - WARN("failed to allocate capture buffer\n"); - err = DSERR_OUTOFMEMORY; - /* but the old buffer might still exist and must be re-prepared */ - } else { - ipDSC->device->buffer = newbuf; - ipDSC->device->buflen = buflen; - } - } - } + *ppDSC = (LPDIRECTSOUNDCAPTURE8)pDSC; - TRACE("returning DS_OK\n"); return DS_OK; } @@ -1720,6 +1487,233 @@ static const IDirectSoundCaptureBuffer8Vtbl dscbvt = IDirectSoundCaptureBufferImpl_GetFXStatus }; +HRESULT DSOUND_CreateDirectSoundCaptureBuffer( + IDirectSoundCaptureImpl *ipDSC, + LPCDSCBUFFERDESC lpcDSCBufferDesc, + LPVOID* ppobj ) +{ + LPWAVEFORMATEX wfex; + TRACE( "(%p,%p)\n", lpcDSCBufferDesc, ppobj ); + + if (ipDSC == NULL) { + WARN("invalid parameter: ipDSC == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if (lpcDSCBufferDesc == NULL) { + WARN("invalid parameter: lpcDSCBufferDesc == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if (ppobj == NULL) { + WARN("invalid parameter: ppobj == NULL\n"); + return DSERR_INVALIDPARAM; + } + + if ( ((lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC)) && + (lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC1))) || + (lpcDSCBufferDesc->dwBufferBytes == 0) || + (lpcDSCBufferDesc->lpwfxFormat == NULL) ) { + WARN("invalid lpcDSCBufferDesc\n"); + *ppobj = NULL; + return DSERR_INVALIDPARAM; + } + + if ( !ipDSC->device) { + WARN("not initialized\n"); + *ppobj = NULL; + return DSERR_UNINITIALIZED; + } + + wfex = lpcDSCBufferDesc->lpwfxFormat; + + if (wfex) { + TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld," + "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n", + wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec, + wfex->nAvgBytesPerSec, wfex->nBlockAlign, + wfex->wBitsPerSample, wfex->cbSize); + + if (wfex->wFormatTag == WAVE_FORMAT_PCM) { + ipDSC->device->pwfx = HeapAlloc(GetProcessHeap(),0,sizeof(WAVEFORMATEX)); + CopyMemory(ipDSC->device->pwfx, wfex, sizeof(WAVEFORMATEX)); + ipDSC->device->pwfx->cbSize = 0; + } else { + ipDSC->device->pwfx = HeapAlloc(GetProcessHeap(),0,sizeof(WAVEFORMATEX)+wfex->cbSize); + CopyMemory(ipDSC->device->pwfx, wfex, sizeof(WAVEFORMATEX)+wfex->cbSize); + } + } else { + WARN("lpcDSCBufferDesc->lpwfxFormat == 0\n"); + *ppobj = NULL; + return DSERR_INVALIDPARAM; /* FIXME: DSERR_BADFORMAT ? */ + } + + *ppobj = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, + sizeof(IDirectSoundCaptureBufferImpl)); + + if ( *ppobj == NULL ) { + WARN("out of memory\n"); + *ppobj = NULL; + return DSERR_OUTOFMEMORY; + } else { + HRESULT err = DS_OK; + LPBYTE newbuf; + DWORD buflen; + IDirectSoundCaptureBufferImpl *This = (IDirectSoundCaptureBufferImpl *)*ppobj; + + This->ref = 1; + This->dsound = ipDSC; + This->dsound->device->capture_buffer = This; + This->notify = NULL; + This->nrofnotifies = 0; + This->hwnotify = NULL; + + This->pdscbd = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY, + lpcDSCBufferDesc->dwSize); + if (This->pdscbd) + CopyMemory(This->pdscbd, lpcDSCBufferDesc, lpcDSCBufferDesc->dwSize); + else { + WARN("no memory\n"); + This->dsound->device->capture_buffer = 0; + HeapFree( GetProcessHeap(), 0, This ); + *ppobj = NULL; + return DSERR_OUTOFMEMORY; + } + + This->lpVtbl = &dscbvt; + + if (ipDSC->device->driver) { + if (This->dsound->device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN) + FIXME("DSDDESC_DOMMSYSTEMOPEN not supported\n"); + + if (This->dsound->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) { + /* allocate buffer from system memory */ + buflen = lpcDSCBufferDesc->dwBufferBytes; + TRACE("desired buflen=%ld, old buffer=%p\n", buflen, ipDSC->device->buffer); + if (ipDSC->device->buffer) + newbuf = HeapReAlloc(GetProcessHeap(),0,ipDSC->device->buffer,buflen); + else + newbuf = HeapAlloc(GetProcessHeap(),0,buflen); + + if (newbuf == NULL) { + WARN("failed to allocate capture buffer\n"); + err = DSERR_OUTOFMEMORY; + /* but the old buffer might still exist and must be re-prepared */ + } else { + ipDSC->device->buffer = newbuf; + ipDSC->device->buflen = buflen; + } + } else { + /* let driver allocate memory */ + ipDSC->device->buflen = lpcDSCBufferDesc->dwBufferBytes; + /* FIXME: */ + HeapFree( GetProcessHeap(), 0, ipDSC->device->buffer); + ipDSC->device->buffer = NULL; + } + + err = IDsCaptureDriver_CreateCaptureBuffer(ipDSC->device->driver, + ipDSC->device->pwfx,0,0,&(ipDSC->device->buflen),&(ipDSC->device->buffer),(LPVOID*)&(ipDSC->device->hwbuf)); + if (err != DS_OK) { + WARN("IDsCaptureDriver_CreateCaptureBuffer failed\n"); + This->dsound->device->capture_buffer = 0; + HeapFree( GetProcessHeap(), 0, This ); + *ppobj = NULL; + return err; + } + } else { + DWORD flags = CALLBACK_FUNCTION; + if (ds_hw_accel != DS_HW_ACCEL_EMULATION) + flags |= WAVE_DIRECTSOUND; + err = mmErr(waveInOpen(&(ipDSC->device->hwi), + ipDSC->device->drvdesc.dnDevNode, ipDSC->device->pwfx, + (DWORD_PTR)DSOUND_capture_callback, (DWORD)ipDSC->device, flags)); + if (err != DS_OK) { + WARN("waveInOpen failed\n"); + This->dsound->device->capture_buffer = 0; + HeapFree( GetProcessHeap(), 0, This ); + *ppobj = NULL; + return err; + } + + buflen = lpcDSCBufferDesc->dwBufferBytes; + TRACE("desired buflen=%ld, old buffer=%p\n", buflen, ipDSC->device->buffer); + if (ipDSC->device->buffer) + newbuf = HeapReAlloc(GetProcessHeap(),0,ipDSC->device->buffer,buflen); + else + newbuf = HeapAlloc(GetProcessHeap(),0,buflen); + if (newbuf == NULL) { + WARN("failed to allocate capture buffer\n"); + err = DSERR_OUTOFMEMORY; + /* but the old buffer might still exist and must be re-prepared */ + } else { + ipDSC->device->buffer = newbuf; + ipDSC->device->buflen = buflen; + } + } + } + + TRACE("returning DS_OK\n"); + return DS_OK; +} + +/******************************************************************************* + * DirectSoundCaptureDevice + */ + +HRESULT DirectSoundCaptureDevice_Create( + DirectSoundCaptureDevice ** ppDevice) +{ + DirectSoundCaptureDevice * device; + TRACE("(%p)\n", ppDevice); + + /* Allocate memory */ + device = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DirectSoundCaptureDevice)); + + if (device == NULL) { + WARN("out of memory\n"); + return DSERR_OUTOFMEMORY; + } + + device->ref = 1; + device->state = STATE_STOPPED; + + InitializeCriticalSection( &(device->lock) ); + device->lock.DebugInfo->Spare[0] = (DWORD_PTR)"DSCAPTURE_lock"; + + *ppDevice = device; + + return DS_OK; +} + +ULONG DirectSoundCaptureDevice_Release( + DirectSoundCaptureDevice * device) +{ + ULONG ref; + TRACE("(%p) ref was %lu\n", device, device->ref); + + device->ref--; + ref=device->ref; + if (device->ref == 0) { + TRACE("deleting object\n"); + if (device->capture_buffer) + IDirectSoundCaptureBufferImpl_Release( + (LPDIRECTSOUNDCAPTUREBUFFER8) device->capture_buffer); + + if (device->driver) { + IDsCaptureDriver_Close(device->driver); + IDsCaptureDriver_Release(device->driver); + } + + HeapFree(GetProcessHeap(), 0, device->pwfx); + device->lock.DebugInfo->Spare[0] = 0; + DeleteCriticalSection( &(device->lock) ); + DSOUND_capture[device->drvdesc.dnDevNode] = NULL; + HeapFree(GetProcessHeap(), 0, device); + TRACE("(%p) released\n", device); + } + return ref; +} + /******************************************************************************* * DirectSoundCapture ClassFactory */ diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index a6defb31f15..ece78f3730c 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -284,6 +284,12 @@ struct IDirectSoundCaptureImpl DirectSoundCaptureDevice *device; }; +HRESULT IDirectSoundCaptureImpl_Create( + LPDIRECTSOUNDCAPTURE8 * ppds); + +/***************************************************************************** + * DirectSoundCaptureDevice implementation structure + */ struct DirectSoundCaptureDevice { /* IDirectSoundCaptureImpl fields */ @@ -314,16 +320,14 @@ struct DirectSoundCaptureDevice CRITICAL_SECTION lock; }; -HRESULT IDirectSoundCaptureImpl_Create( - LPDIRECTSOUNDCAPTURE8 * ppds); +HRESULT DirectSoundCaptureDevice_Create( + DirectSoundCaptureDevice ** ppDevice); -HRESULT DSOUND_CaptureCreate( - LPDIRECTSOUNDCAPTURE *ppDSC, - IUnknown *pUnkOuter); +ULONG DirectSoundCaptureDevice_AddRef( + DirectSoundCaptureDevice * device); -HRESULT DSOUND_CaptureCreate8( - LPDIRECTSOUNDCAPTURE8 *ppDSC8, - IUnknown *pUnkOuter); +ULONG DirectSoundCaptureDevice_Release( + DirectSoundCaptureDevice * device); /***************************************************************************** * IDirectSoundCaptureBuffer implementation structure @@ -347,6 +351,11 @@ struct IDirectSoundCaptureBufferImpl PIDSDRIVERNOTIFY hwnotify; }; +HRESULT DSOUND_CreateDirectSoundCaptureBuffer( + IDirectSoundCaptureImpl *ipDSC, + LPCDSCBUFFERDESC lpcDSCBufferDesc, + LPVOID * ppobj); + /***************************************************************************** * IDirectSoundFullDuplex implementation structure */ -- 2.11.4.GIT