Esempio n. 1
0
/***********************************************************************
 *           MSACM_UnregisterDriver()
 */
PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
{
    PWINE_ACMDRIVERID pNextACMDriverID;

    while (p->pACMDriverList)
	acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);

    HeapFree(MSACM_hHeap, 0, p->pszDriverAlias);
    HeapFree(MSACM_hHeap, 0, p->pszFileName);
    HeapFree(MSACM_hHeap, 0, p->aFormatTag);

    if (p == MSACM_pFirstACMDriverID)
	MSACM_pFirstACMDriverID = p->pNextACMDriverID;
    if (p == MSACM_pLastACMDriverID)
	MSACM_pLastACMDriverID = p->pPrevACMDriverID;

    if (p->pPrevACMDriverID)
	p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
    if (p->pNextACMDriverID)
	p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;

    pNextACMDriverID = p->pNextACMDriverID;

    if (p->pLocalDriver) MSACM_UnregisterLocalDriver(p->pLocalDriver);
    HeapFree(MSACM_hHeap, 0, p);

    return pNextACMDriverID;
}
Esempio n. 2
0
/***********************************************************************
 *           acmFilterTagEnumW (MSACM32.@)
 */
MMRESULT WINAPI acmFilterTagEnumW(HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
                                  ACMFILTERTAGENUMCBW fnCallback,
                                  DWORD_PTR dwInstance, DWORD fdwEnum)
{
    PWINE_ACMDRIVERID		padid;
    unsigned int			i;

    TRACE("(%p, %p, %p, %ld, %d)\n",
	  had, paftd, fnCallback, dwInstance, fdwEnum);

    if (paftd->cbStruct < sizeof(*paftd)) return MMSYSERR_INVALPARAM;

    if (had) FIXME("had != NULL, not supported\n");

    for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
	/* should check for codec only */
	if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
	    acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {

	    for (i = 0; i < padid->cFilterTags; i++) {
		paftd->dwFilterTagIndex = i;
		if (acmFilterTagDetailsW(had, paftd, ACM_FILTERTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
		    if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
			padid = NULL;
			break;
		    }
		}
	    }
	    acmDriverClose(had, 0);
	}
    }
    return MMSYSERR_NOERROR;
}
Esempio n. 3
0
/***********************************************************************
 *           MSACM_FillCache
 */
static BOOL MSACM_FillCache(PWINE_ACMDRIVERID padid)
{
    HACMDRIVER		        had = 0;
    unsigned int		        ntag;
    ACMDRIVERDETAILSW	        add;
    ACMFORMATTAGDETAILSW        aftd;

    if (acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != 0)
	return FALSE;

    padid->aFormatTag = NULL;
    add.cbStruct = sizeof(add);
    if (MSACM_Message(had, ACMDM_DRIVER_DETAILS, (LPARAM)&add,  0))
	goto errCleanUp;

    if (add.cFormatTags > 0) {
	padid->aFormatTag = HeapAlloc(MSACM_hHeap, HEAP_ZERO_MEMORY,
				      add.cFormatTags * sizeof(padid->aFormatTag[0]));
	if (!padid->aFormatTag) goto errCleanUp;
    }

    padid->cFormatTags = add.cFormatTags;
    padid->cFilterTags = add.cFilterTags;
    padid->fdwSupport  = add.fdwSupport;

    aftd.cbStruct = sizeof(aftd);

    for (ntag = 0; ntag < add.cFormatTags; ntag++) {
	aftd.dwFormatTagIndex = ntag;
	if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)&aftd, ACM_FORMATTAGDETAILSF_INDEX)) {
	    TRACE("IIOs (%s)\n", debugstr_w(padid->pszDriverAlias));
	    goto errCleanUp;
	}
	padid->aFormatTag[ntag].dwFormatTag = aftd.dwFormatTag;
	padid->aFormatTag[ntag].cbwfx = aftd.cbFormatSize;
    }

    acmDriverClose(had, 0);

    return TRUE;

errCleanUp:
    if (had) acmDriverClose(had, 0);
    HeapFree(MSACM_hHeap, 0, padid->aFormatTag);
    padid->aFormatTag = NULL;
    return FALSE;
}
Esempio n. 4
0
/***********************************************************************
 *           acmFormatDetailsW (MSACM32.@)
 */
MMRESULT WINAPI acmFormatDetailsW(HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails)
{
    MMRESULT			mmr;
    static const WCHAR		fmt1[] = {'%','d',' ','H','z',0};
    static const WCHAR		fmt2[] = {';',' ','%','d',' ','b','i','t','s',0};

    TRACE("(%p, %p, %d)\n", had, pafd, fdwDetails);

    if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;

    switch (fdwDetails) {
    case ACM_FORMATDETAILSF_FORMAT:
	if (pafd->dwFormatTag != pafd->pwfx->wFormatTag) {
	    mmr = MMSYSERR_INVALPARAM;
	    break;
	}
	if (had == NULL) {
	    PWINE_ACMDRIVERID		padid;

	    mmr = ACMERR_NOTPOSSIBLE;
	    for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
		/* should check for codec only */
		if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
		    acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
		    mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
		    acmDriverClose(had, 0);
		    if (mmr == MMSYSERR_NOERROR) break;
		}
	    }
	} else {
	    mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
	}
	break;
    case ACM_FORMATDETAILSF_INDEX:
	/* should check pafd->dwFormatIndex < aftd->cStandardFormats */
	mmr = MSACM_Message(had, ACMDM_FORMAT_DETAILS, (LPARAM)pafd, fdwDetails);
	break;
    default:
	WARN("Unknown fdwDetails %08x\n", fdwDetails);
	mmr = MMSYSERR_INVALFLAG;
	break;
    }

    if (mmr == MMSYSERR_NOERROR && pafd->szFormat[0] == 0) {
	wsprintfW(pafd->szFormat, fmt1, pafd->pwfx->nSamplesPerSec);
	if (pafd->pwfx->wBitsPerSample) {
	    wsprintfW(pafd->szFormat + lstrlenW(pafd->szFormat), fmt2,
		      pafd->pwfx->wBitsPerSample);
	}
        MultiByteToWideChar( CP_ACP, 0, (pafd->pwfx->nChannels == 1) ? "; Mono" : "; Stereo", -1,
                             pafd->szFormat + strlenW(pafd->szFormat),
                             sizeof(pafd->szFormat)/sizeof(WCHAR) - strlenW(pafd->szFormat) );
    }

    TRACE("=> %d\n", mmr);
    return mmr;
}
Esempio n. 5
0
MMRESULT WINAPI acmFormatEnumW(HACMDRIVER had, PACMFORMATDETAILSW pafd,
			       ACMFORMATENUMCBW fnCallback, DWORD dwInstance,
			       DWORD fdwEnum)
{
    PWINE_ACMDRIVERID		padid;
    WAVEFORMATEX		wfxRef;
    BOOL			ret;

    TRACE("(%p, %p, %p, %d, %d)\n",
	  had, pafd, fnCallback, dwInstance, fdwEnum);

    if (!pafd)
        return MMSYSERR_INVALPARAM;

    if (pafd->cbStruct < sizeof(*pafd))
        return MMSYSERR_INVALPARAM;

    if (fdwEnum & (ACM_FORMATENUMF_WFORMATTAG|ACM_FORMATENUMF_NCHANNELS|
		   ACM_FORMATENUMF_NSAMPLESPERSEC|ACM_FORMATENUMF_WBITSPERSAMPLE|
		   ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST))
        wfxRef = *pafd->pwfx;

    if ((fdwEnum & ACM_FORMATENUMF_HARDWARE) &&
	!(fdwEnum & (ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT)))
	return MMSYSERR_INVALPARAM;

    if ((fdwEnum & ACM_FORMATENUMF_WFORMATTAG) &&
	(pafd->dwFormatTag != pafd->pwfx->wFormatTag))
	return MMSYSERR_INVALPARAM;

    if (fdwEnum & (ACM_FORMATENUMF_CONVERT|ACM_FORMATENUMF_SUGGEST|
		   ACM_FORMATENUMF_INPUT|ACM_FORMATENUMF_OUTPUT))
	FIXME("Unsupported fdwEnum values %08x\n", fdwEnum);

    if (had) {
	HACMDRIVERID	hadid;

	if (acmDriverID((HACMOBJ)had, &hadid, 0) != MMSYSERR_NOERROR)
	    return MMSYSERR_INVALHANDLE;
	MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid), had, pafd, &wfxRef,
			       fnCallback, dwInstance, fdwEnum);
	return MMSYSERR_NOERROR;
    }
    for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
	    /* should check for codec only */
	    if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
		acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
		continue;
	    ret = MSACM_FormatEnumHelper(padid, had, pafd, &wfxRef,
					 fnCallback, dwInstance, fdwEnum);
	    acmDriverClose(had, 0);
	    if (!ret) break;
    }
    return MMSYSERR_NOERROR;
}
Esempio n. 6
0
/***********************************************************************
 *           acmFilterDetailsW (MSACM32.@)
 */
MMRESULT WINAPI acmFilterDetailsW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
				  DWORD fdwDetails)
{
    MMRESULT			mmr;
    ACMFILTERTAGDETAILSA	aftd;

    TRACE("(%p, %p, %d)\n", had, pafd, fdwDetails);

    memset(&aftd, 0, sizeof(aftd));
    aftd.cbStruct = sizeof(aftd);

    if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;

    switch (fdwDetails) {
    case ACM_FILTERDETAILSF_FILTER:
	if (pafd->dwFilterTag != pafd->pwfltr->dwFilterTag) {
	    mmr = MMSYSERR_INVALPARAM;
	    break;
	}
	if (had == NULL) {
	    PWINE_ACMDRIVERID		padid;

	    mmr = ACMERR_NOTPOSSIBLE;
	    for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
		/* should check for codec only */
		if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
		    acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
		    mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS,
					(LPARAM)pafd, (LPARAM)fdwDetails);
		    acmDriverClose(had, 0);
		    if (mmr == MMSYSERR_NOERROR) break;
		}
	    }
	} else {
	    mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
	}
	break;
    case ACM_FILTERDETAILSF_INDEX:
	/* should check pafd->dwFilterIndex < aftd->cStandardFilters */
	mmr = MSACM_Message(had, ACMDM_FILTER_DETAILS, (LPARAM)pafd, fdwDetails);
	break;
    default:
	WARN("Unknown fdwDetails %08x\n", fdwDetails);
	mmr = MMSYSERR_INVALFLAG;
	break;
    }

    TRACE("=> %d\n", mmr);
    return mmr;
}
Esempio n. 7
0
/***********************************************************************
 *           acmFormatSuggest (MSACM32.@)
 */
MMRESULT WINAPI acmFormatSuggest(HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
				 PWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest)
{
    ACMDRVFORMATSUGGEST	adfg;
    MMRESULT		mmr;

    TRACE("(%p, %p, %p, %d, %d)\n",
	  had, pwfxSrc, pwfxDst, cbwfxDst, fdwSuggest);

    if (!pwfxSrc || !pwfxDst)
        return MMSYSERR_INVALPARAM;

    if (fdwSuggest & ~(ACM_FORMATSUGGESTF_NCHANNELS|ACM_FORMATSUGGESTF_NSAMPLESPERSEC|
		       ACM_FORMATSUGGESTF_WBITSPERSAMPLE|ACM_FORMATSUGGESTF_WFORMATTAG))
	return MMSYSERR_INVALFLAG;

    adfg.cbStruct = sizeof(adfg);
    adfg.fdwSuggest = fdwSuggest;
    adfg.pwfxSrc = pwfxSrc;
    adfg.cbwfxSrc = (pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) ?
	sizeof(WAVEFORMATEX) : (sizeof(WAVEFORMATEX) + pwfxSrc->cbSize);
    adfg.pwfxDst = pwfxDst;
    adfg.cbwfxDst = cbwfxDst;

    if (had == NULL) {
	PWINE_ACMDRIVERID	padid;

	/* MS doc says: ACM finds the best suggestion.
	 * Well, first found will be the "best"
	 */
	mmr = ACMERR_NOTPOSSIBLE;
	for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
	    /* should check for codec only */
	    if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
		acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
		continue;

	    if (MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L) == MMSYSERR_NOERROR) {
		mmr = MMSYSERR_NOERROR;
		break;
	    }
	    acmDriverClose(had, 0);
	}
    } else {
	mmr = MSACM_Message(had, ACMDM_FORMAT_SUGGEST, (LPARAM)&adfg, 0L);
    }
    return mmr;
}
BOOL CALLBACK acmDriverEnumCallback( HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport ){
	MMRESULT mmr;
	HACMDRIVER driver;
	int i;

	ACMDRIVERDETAILS details;
	details.cbStruct = sizeof(ACMDRIVERDETAILS);
	mmr = acmDriverDetails( hadid, &details, 0 );

	mmr = acmDriverOpen( &driver, hadid, 0 );

	for(i = 0; i < details.cFormatTags; i++ ){
	  ACMFORMATTAGDETAILS fmtDetails;
	  ZeroMemory( &fmtDetails, sizeof(fmtDetails) );
	  fmtDetails.cbStruct = sizeof(ACMFORMATTAGDETAILS);
	  fmtDetails.dwFormatTagIndex = i;
	  mmr = acmFormatTagDetails( driver, &fmtDetails, ACM_FORMATTAGDETAILSF_INDEX );
	  if( fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC ) {
		 /* fprintf(stderr, "supported codec: %s\n" ,details.szLongName ); */
	      if( fmtDetails.dwFormatTag == WAVE_FORMAT_MSG723 )
		  {
			  g_g723Drivers = /* 1 */ 0;
/*	!		  fprintf(stderr, "Find Codec  %s\n" ,details.szLongName ); */
#if 0
			  fprintf(stderr, "G723 cFormatTags %i\n" ,details.cFormatTags );
			  fprintf(stderr, "G723 cFilterTags %i\n" ,details.cFilterTags);
#endif
			  return -1;
		  }
	      else if( fmtDetails.dwFormatTag == WAVE_FORMAT_GSM610 )
		  {
			  g_gsmDrivers = 1;
/* !			  fprintf(stderr, "Find Codec  %s\n" ,details.szLongName ); */
			  return -1;
		  }
	  }
	  else
	  {
/* !		  fprintf(stderr, "Unsupported codec: %s\n" ,details.szLongName ); */
	  }
	}
	mmr = acmDriverClose( driver, 0 );
	return -1;
}
Esempio n. 9
0
/***********************************************************************
 *           acmStreamClose (MSACM32.@)
 */
MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
{
    PWINE_ACMSTREAM	was;
    MMRESULT		ret;

    TRACE("(%p, %d)\n", has, fdwClose);

    if ((was = ACM_GetStream(has)) == NULL) {
        WARN("invalid handle\n");
	return MMSYSERR_INVALHANDLE;
    }
    ret = MSACM_Message((HACMDRIVER)was->pDrv, ACMDM_STREAM_CLOSE, (LPARAM)&was->drvInst, 0);
    if (ret == MMSYSERR_NOERROR) {
	if (was->hAcmDriver)
	    acmDriverClose(was->hAcmDriver, 0L);
	HeapFree(MSACM_hHeap, 0, was);
    }
    TRACE("=> (%d)\n", ret);
    return ret;
}
Esempio n. 10
0
MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
{
    PWINE_ACMSTREAM	was;
    MMRESULT		ret;
		
    TRACE("(0x%08x, %ld)\n", has, fdwClose);
    
    if ((was = ACM_GetStream(has)) == NULL) {
	return MMSYSERR_INVALHANDLE;
    }
    ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
    if (ret == MMSYSERR_NOERROR) {
	if (was->hAcmDriver)
	    acmDriverClose(was->hAcmDriver, 0L);	
	HeapFree(MSACM_hHeap, 0, was);
	CodecRelease();
    }
    TRACE("=> (%d)\n", ret);
    return ret;
}
Esempio n. 11
0
/***********************************************************************
 *           acmDriverDetailsW (MSACM32.@)
 */
MMRESULT WINAPI acmDriverDetailsW(HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails)
{
    HACMDRIVER acmDrvr;
    MMRESULT mmr;

    TRACE("(%p, %p, %08x)\n", hadid, padd, fdwDetails);

    if (!padd) {
        WARN("invalid parameter\n");
        return MMSYSERR_INVALPARAM;
    }

    if (padd->cbStruct < 4) {
        WARN("invalid parameter\n");
        return MMSYSERR_INVALPARAM;
    }

    if (fdwDetails) {
        WARN("invalid flag\n");
	return MMSYSERR_INVALFLAG;
    }

    mmr = acmDriverOpen(&acmDrvr, hadid, 0);
    if (mmr == MMSYSERR_NOERROR) {
        ACMDRIVERDETAILSW paddw;
        paddw.cbStruct = sizeof(paddw);
        mmr = MSACM_Message(acmDrvr, ACMDM_DRIVER_DETAILS, (LPARAM)&paddw,  0);

	acmDriverClose(acmDrvr, 0);
        paddw.cbStruct = min(padd->cbStruct, sizeof(*padd));
        memcpy(padd, &paddw, paddw.cbStruct);
    }
    else if (mmr == MMSYSERR_NODRIVER)
        return MMSYSERR_NOTSUPPORTED;

    return mmr;
}
Esempio n. 12
0
/***********************************************************************
 *           acmFilterEnumW (MSACM32.@)
 */
MMRESULT WINAPI acmFilterEnumW(HACMDRIVER had, PACMFILTERDETAILSW pafd,
                               ACMFILTERENUMCBW fnCallback,
                               DWORD_PTR dwInstance, DWORD fdwEnum)
{
    PWINE_ACMDRIVERID		padid;
    BOOL			ret;

    TRACE("(%p, %p, %p, %ld, %d)\n",
	  had, pafd, fnCallback, dwInstance, fdwEnum);

    if (pafd->cbStruct < sizeof(*pafd)) return MMSYSERR_INVALPARAM;

    if (fdwEnum & ~(ACM_FILTERENUMF_DWFILTERTAG))
	FIXME("Unsupported fdwEnum values\n");

    if (had) {
	HACMDRIVERID	hadid;

	if (acmDriverID((HACMOBJ)had, &hadid, 0) != MMSYSERR_NOERROR)
	    return MMSYSERR_INVALHANDLE;
	MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid), had, pafd,
			       fnCallback, dwInstance, fdwEnum);
	return MMSYSERR_NOERROR;
    }
    for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
	    /* should check for codec only */
	    if ((padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
		acmDriverOpen(&had, (HACMDRIVERID)padid, 0) != MMSYSERR_NOERROR)
		continue;
	    ret = MSACM_FilterEnumHelper(padid, had, pafd,
					 fnCallback, dwInstance, fdwEnum);
	    acmDriverClose(had, 0);
	    if (!ret) break;
    }
    return MMSYSERR_NOERROR;
}
Esempio n. 13
0
/***********************************************************************
 *           acmFormatTagEnumW (MSACM32.@)
 */
MMRESULT WINAPI acmFormatTagEnumW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
				  ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance,
				  DWORD fdwEnum)
{
    PWINE_ACMDRIVERID		padid;
    unsigned int			i;
    BOOL			bPcmDone = FALSE;

    TRACE("(%p, %p, %p, %d, %d)\n",
	  had, paftd, fnCallback, dwInstance, fdwEnum);

    if (!paftd)
        return MMSYSERR_INVALPARAM;

    if (paftd->cbStruct < sizeof(*paftd))
        return MMSYSERR_INVALPARAM;

    if (fdwEnum != 0)
        return MMSYSERR_INVALFLAG;

    /* (WS) MSDN info page says that if had != 0, then we should find
     * the specific driver to get its tags from. Therefore I'm removing
     * the FIXME call and adding a search block below. It also seems
     * that the lack of this functionality was the responsible for 
     * codecs to be multiply and incorrectly listed. 
     */

    /* if (had) FIXME("had != NULL, not supported\n"); */

    if (had) {

       if (acmDriverID((HACMOBJ)had, (HACMDRIVERID *)&padid, 0) != MMSYSERR_NOERROR)
          return MMSYSERR_INVALHANDLE;

       for (i = 0; i < padid->cFormatTags; i++) {
	  paftd->dwFormatTagIndex = i;
	  if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
	  (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
	     if (paftd->dwFormatTag == WAVE_FORMAT_PCM) {
	        if (paftd->szFormatTag[0] == 0)
		   MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
			 sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
		/* (WS) I'm preserving this PCM hack since it seems to be
		 * correct. Please notice this block was borrowed from
		 * below.
	  	 */
		if (bPcmDone) continue;
		   bPcmDone = TRUE;
	     }
	     if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) 
                return MMSYSERR_NOERROR;
	  }
       }

    }

    /* if had==0 then search for the first suitable driver */
    else {
       for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
          /* should check for codec only */
          if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
	     acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == MMSYSERR_NOERROR) {
	     for (i = 0; i < padid->cFormatTags; i++) {
	        paftd->dwFormatTagIndex = i;
	        if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
	           (LPARAM)paftd, ACM_FORMATTAGDETAILSF_INDEX) == MMSYSERR_NOERROR) {
	           if (paftd->dwFormatTag == WAVE_FORMAT_PCM) {
		      if (paftd->szFormatTag[0] == 0)
		         MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
				 sizeof(paftd->szFormatTag)/sizeof(WCHAR) );
		      /* FIXME (EPP): I'm not sure this is the correct
		       * algorithm (should make more sense to apply the same
		       * for all already loaded formats, but this will do
	  	       * for now
	       	       */
		      if (bPcmDone) continue;
		         bPcmDone = TRUE;
		   }
		   if (!(fnCallback)((HACMDRIVERID)padid, paftd, dwInstance, padid->fdwSupport)) {
                      acmDriverClose(had, 0);
                      return MMSYSERR_NOERROR;
		   }
	        }
	     }
          }
          acmDriverClose(had, 0);
       }
    }
    return MMSYSERR_NOERROR;
}
Esempio n. 14
0
/***********************************************************************
 *           acmFormatTagDetailsW (MSACM32.@)
 */
MMRESULT WINAPI acmFormatTagDetailsW(HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
				     DWORD fdwDetails)
{
    PWINE_ACMDRIVERID	padid;
    MMRESULT		mmr = ACMERR_NOTPOSSIBLE;

    TRACE("(%p, %p, %d)\n", had, paftd, fdwDetails);

    if (fdwDetails & ~(ACM_FORMATTAGDETAILSF_FORMATTAG|ACM_FORMATTAGDETAILSF_INDEX|
		       ACM_FORMATTAGDETAILSF_LARGESTSIZE))
	return MMSYSERR_INVALFLAG;

    switch (fdwDetails) {
    case ACM_FORMATTAGDETAILSF_FORMATTAG:
	if (had == NULL) {
	    for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
		/* should check for codec only */
		if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
		    MSACM_FindFormatTagInCache(padid, paftd->dwFormatTag, NULL) &&
		    acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {
		    mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
		    acmDriverClose(had, 0);
		    if (mmr == MMSYSERR_NOERROR) break;
		}
	    }
	} else {
	    PWINE_ACMDRIVER	pad = MSACM_GetDriver(had);

	    if (pad && MSACM_FindFormatTagInCache(pad->obj.pACMDriverID, paftd->dwFormatTag, NULL))
		mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
	}
	break;

    case ACM_FORMATTAGDETAILSF_INDEX:
	if (had != NULL) {
	    PWINE_ACMDRIVER	pad = MSACM_GetDriver(had);

	    if (pad && paftd->dwFormatTagIndex < pad->obj.pACMDriverID->cFormatTags)
		mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
	}
	break;

    case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
	if (had == NULL) {
	    ACMFORMATTAGDETAILSW	tmp;
	    DWORD			ft = paftd->dwFormatTag;

	    for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
		/* should check for codec only */
		if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) &&
		    acmDriverOpen(&had, (HACMDRIVERID)padid, 0) == 0) {

		    memset(&tmp, 0, sizeof(tmp));
		    tmp.cbStruct = sizeof(tmp);
		    tmp.dwFormatTag = ft;

		    if (MSACM_Message(had, ACMDM_FORMATTAG_DETAILS,
				      (LPARAM)&tmp, fdwDetails) == MMSYSERR_NOERROR) {
			if (mmr == ACMERR_NOTPOSSIBLE ||
			    paftd->cbFormatSize < tmp.cbFormatSize) {
			    *paftd = tmp;
			    mmr = MMSYSERR_NOERROR;
			}
		    }
		    acmDriverClose(had, 0);
		}
	    }
	} else {
	    mmr = MSACM_Message(had, ACMDM_FORMATTAG_DETAILS, (LPARAM)paftd, fdwDetails);
	}
	break;

    default:
	WARN("Unsupported fdwDetails=%08x\n", fdwDetails);
	mmr = MMSYSERR_ERROR;
    }

    if (mmr == MMSYSERR_NOERROR &&
	paftd->dwFormatTag == WAVE_FORMAT_PCM && paftd->szFormatTag[0] == 0)
        MultiByteToWideChar( CP_ACP, 0, "PCM", -1, paftd->szFormatTag,
                             sizeof(paftd->szFormatTag)/sizeof(WCHAR) );

    return mmr;
}
Esempio n. 15
0
static BOOL CALLBACK MSACM_FillFormatTagsCB(HACMDRIVERID hadid,
					    PACMFORMATTAGDETAILSA paftd,
					    DWORD dwInstance, DWORD fdwSupport)
{
    struct MSACM_FillFormatData*	affd = (struct MSACM_FillFormatData*)dwInstance;

    switch (affd->mode) {
    case WINE_ACMFF_TAG:
	if (SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
				CB_FINDSTRINGEXACT,
				(WPARAM)-1, (LPARAM)paftd->szFormatTag) == CB_ERR)
	    SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG,
				CB_ADDSTRING, 0, (DWORD)paftd->szFormatTag);
	break;
    case WINE_ACMFF_FORMAT:
	if (strcmp(affd->szFormatTag, paftd->szFormatTag) == 0) {
	    HACMDRIVER		had;

	    if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) {
		ACMFORMATDETAILSA	afd;
               unsigned int            i, len;
		MMRESULT		mmr;
		char			buffer[ACMFORMATDETAILS_FORMAT_CHARS+16];

		afd.cbStruct = sizeof(afd);
		afd.dwFormatTag = paftd->dwFormatTag;
		afd.pwfx = HeapAlloc(MSACM_hHeap, 0, paftd->cbFormatSize);
		if (!afd.pwfx) return FALSE;
		afd.pwfx->wFormatTag = paftd->dwFormatTag;
		afd.pwfx->cbSize = paftd->cbFormatSize;
		afd.cbwfx = paftd->cbFormatSize;

		for (i = 0; i < paftd->cStandardFormats; i++) {
		    afd.dwFormatIndex = i;
		    mmr = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX);
		    if (mmr == MMSYSERR_NOERROR) {
                       lstrcpynA(buffer, afd.szFormat, ACMFORMATTAGDETAILS_FORMATTAG_CHARS + 1);
                       len = strlen(buffer);
                       memset(buffer+len, ' ', ACMFORMATTAGDETAILS_FORMATTAG_CHARS - len);
			wsprintfA(buffer + ACMFORMATTAGDETAILS_FORMATTAG_CHARS,
				  "%d Ko/s",
				  (afd.pwfx->nAvgBytesPerSec + 512) / 1024);
			SendDlgItemMessageA(affd->hWnd,
					    IDD_ACMFORMATCHOOSE_CMB_FORMAT,
					    CB_ADDSTRING, 0, (DWORD)buffer);
		    }
		}
		acmDriverClose(had, 0);
		SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT,
				    CB_SETCURSEL, 0, 0);
		HeapFree(MSACM_hHeap, 0, afd.pwfx);
	    }
	}
	break;
    case WINE_ACMFF_WFX:
	if (strcmp(affd->szFormatTag, paftd->szFormatTag) == 0) {
	    HACMDRIVER		had;

	    if (acmDriverOpen(&had, hadid, 0) == MMSYSERR_NOERROR) {
		ACMFORMATDETAILSA	afd;

		afd.cbStruct = sizeof(afd);
		afd.dwFormatTag = paftd->dwFormatTag;
		afd.pwfx = affd->afc->pwfx;
		afd.cbwfx = affd->afc->cbwfx;

		afd.dwFormatIndex = SendDlgItemMessageA(affd->hWnd, IDD_ACMFORMATCHOOSE_CMB_FORMAT,
							CB_GETCURSEL, 0, 0);
		affd->ret = acmFormatDetailsA(had, &afd, ACM_FORMATDETAILSF_INDEX);
		acmDriverClose(had, 0);
		return TRUE;
	    }
	}
	break;
    default:
	FIXME("Unknown mode (%d)\n", affd->mode);
	break;
    }
    return TRUE;
}
Esempio n. 16
0
void
acm_cv_shutdown (void)
{
        if (hDrv) acmDriverClose(hDrv, 0);
        hDrv = 0;
}
Esempio n. 17
0
/***********************************************************************
 *           acmStreamOpen (MSACM32.@)
 */
MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had,
                              PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst,
                              PWAVEFILTER pwfltr, DWORD_PTR dwCallback,
                              DWORD_PTR dwInstance, DWORD fdwOpen)
{
    PWINE_ACMSTREAM	was;
    PWINE_ACMDRIVER	wad;
    MMRESULT		ret;
    int			wfxSrcSize;
    int			wfxDstSize;
    WAVEFORMATEX	wfxSrc, wfxDst;

    TRACE("(%p, %p, %p, %p, %p, %ld, %ld, %d)\n",
	  phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);

    /* NOTE: pwfxSrc and/or pwfxDst can point to a structure smaller than
     * WAVEFORMATEX so don't use them directly when not sure */
    if (pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) {
        memcpy(&wfxSrc, pwfxSrc, sizeof(PCMWAVEFORMAT));
        wfxSrc.wBitsPerSample = pwfxSrc->wBitsPerSample;
        wfxSrc.cbSize = 0;
        pwfxSrc = &wfxSrc;
    }

    if (pwfxDst->wFormatTag == WAVE_FORMAT_PCM) {
        memcpy(&wfxDst, pwfxDst, sizeof(PCMWAVEFORMAT));
        wfxDst.wBitsPerSample = pwfxDst->wBitsPerSample;
        wfxDst.cbSize = 0;
        pwfxDst = &wfxDst;
    }

    TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%u, nAvgBytesPerSec=%u, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
	  pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
	  pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);

    TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%u, nAvgBytesPerSec=%u, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
	  pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
	  pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);

    /* (WS) In query mode, phas should be NULL. If it is not, then instead
     * of returning an error we are making sure it is NULL, preventing some
     * applications that pass garbage for phas from crashing.
     */
    if (fdwOpen & ACM_STREAMOPENF_QUERY) phas = NULL;

    if (pwfltr && (pwfxSrc->wFormatTag != pwfxDst->wFormatTag)) {
        WARN("invalid parameter\n");
        return MMSYSERR_INVALPARAM;
    }

    wfxSrcSize = wfxDstSize = sizeof(WAVEFORMATEX);
    if (pwfxSrc->wFormatTag != WAVE_FORMAT_PCM) wfxSrcSize += pwfxSrc->cbSize;
    if (pwfxDst->wFormatTag != WAVE_FORMAT_PCM) wfxDstSize += pwfxDst->cbSize;

    was = HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize +
		    ((pwfltr) ? sizeof(WAVEFILTER) : 0));
    if (was == NULL) {
        WARN("no memory\n");
	return MMSYSERR_NOMEM;
    }

    was->drvInst.cbStruct = sizeof(was->drvInst);
    was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
    memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
    was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
    memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
    if (pwfltr) {
	was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
	memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
    } else {
	was->drvInst.pwfltr = NULL;
    }
    was->drvInst.dwCallback = dwCallback;
    was->drvInst.dwInstance = dwInstance;
    was->drvInst.fdwOpen = fdwOpen;
    was->drvInst.fdwDriver = 0L;
    was->drvInst.dwDriver = 0L;
    /* real value will be stored once ACMDM_STREAM_OPEN succeeds */
    was->drvInst.has = 0L;

    if (had) {
	if (!(wad = MSACM_GetDriver(had))) {
	    ret = MMSYSERR_INVALPARAM;
	    goto errCleanUp;
	}

	was->obj.dwType = WINE_ACMOBJ_STREAM;
	was->obj.pACMDriverID = wad->obj.pACMDriverID;
	was->pDrv = wad;
	was->hAcmDriver = 0; /* not to close it in acmStreamClose */

	ret = MSACM_Message((HACMDRIVER)wad, ACMDM_STREAM_OPEN, (LPARAM)&was->drvInst, 0L);
	if (ret != MMSYSERR_NOERROR)
	    goto errCleanUp;
    } else {
	PWINE_ACMDRIVERID wadi;

	ret = ACMERR_NOTPOSSIBLE;
	for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID) {
	    if ((wadi->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) ||
		!MSACM_FindFormatTagInCache(wadi, pwfxSrc->wFormatTag, NULL) ||
		!MSACM_FindFormatTagInCache(wadi, pwfxDst->wFormatTag, NULL))
		continue;
	    ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
	    if (ret != MMSYSERR_NOERROR)
		continue;
	    if ((wad = MSACM_GetDriver(had)) != 0) {
		was->obj.dwType = WINE_ACMOBJ_STREAM;
		was->obj.pACMDriverID = wad->obj.pACMDriverID;
		was->pDrv = wad;
		was->hAcmDriver = had;

		ret = MSACM_Message((HACMDRIVER)wad, ACMDM_STREAM_OPEN, (LPARAM)&was->drvInst, 0L);
		TRACE("%s => %08x\n", debugstr_w(wadi->pszDriverAlias), ret);
		if (ret == MMSYSERR_NOERROR) {
		    if (fdwOpen & ACM_STREAMOPENF_QUERY) {
			MSACM_Message((HACMDRIVER)wad, ACMDM_STREAM_CLOSE, (LPARAM)&was->drvInst, 0);
			acmDriverClose(had, 0L);
		    }
		    break;
		}
	    }
	    /* no match, close this acm driver and try next one */
	    acmDriverClose(had, 0L);
	}
	if (ret != MMSYSERR_NOERROR) {
	    ret = ACMERR_NOTPOSSIBLE;
	    goto errCleanUp;
	}
    }
    ret = MMSYSERR_NOERROR;
    was->drvInst.has = (HACMSTREAM)was;
    if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
	if (phas)
	    *phas = (HACMSTREAM)was;
	TRACE("=> (%d)\n", ret);
	return ret;
    }
errCleanUp:
    if (phas)
	*phas = NULL;
    HeapFree(MSACM_hHeap, 0, was);
    TRACE("=> (%d)\n", ret);
    return ret;
}
Esempio n. 18
0
/***********************************************************************
 *           acmDriverMessage (MSACM32.@)
 *
 * Note: MSDN documentation (July 2001) is incomplete. This function
 * accepts sending messages to an HACMDRIVERID in addition to the
 * documented HACMDRIVER. In fact, for DRV_QUERYCONFIGURE and DRV_CONFIGURE, 
 * this might actually be the required mode of operation.
 *
 * Note: For DRV_CONFIGURE, msacm supplies its own DRVCONFIGINFO structure
 * when the application fails to supply one. Some native drivers depend on
 * this and refuse to display unless a valid DRVCONFIGINFO structure is
 * built and supplied.
 */
LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
{
    TRACE("(%p, %04x, %08lx, %08lx\n", had, uMsg, lParam1, lParam2);

    if ((uMsg >= ACMDM_USER && uMsg < ACMDM_RESERVED_LOW) ||
	uMsg == ACMDM_DRIVER_ABOUT ||
	uMsg == DRV_QUERYCONFIGURE ||
	uMsg == DRV_CONFIGURE)
    {
        PWINE_ACMDRIVERID padid;
        LRESULT lResult;
        LPDRVCONFIGINFO pConfigInfo = NULL;
        LPWSTR section_name = NULL;
        LPWSTR alias_name = NULL;

        /* Check whether handle is an HACMDRIVERID */
        padid  = MSACM_GetDriverID((HACMDRIVERID)had);
        
        /* If the message is DRV_CONFIGURE, and the application provides no
           DRVCONFIGINFO structure, msacm must supply its own.
         */
        if (uMsg == DRV_CONFIGURE && lParam2 == 0) {
            LPWSTR pAlias;
            
            /* Get the alias from the HACMDRIVERID */
            if (padid) {
                pAlias = padid->pszDriverAlias;
                if (pAlias == NULL) {
                    WARN("DRV_CONFIGURE: no alias for this driver, cannot self-supply alias\n");
                }
            } else {
                FIXME("DRV_CONFIGURE: reverse lookup HACMDRIVER -> HACMDRIVERID not implemented\n");
                pAlias = NULL;
            }
        
            if (pAlias != NULL) {
                /* DRVCONFIGINFO is only 12 bytes long, but native msacm
                 * reports a 16-byte structure to codecs, so allocate 16 bytes,
                 * just to be on the safe side.
                 */
                const unsigned int iStructSize = 16;
                pConfigInfo = HeapAlloc(MSACM_hHeap, 0, iStructSize);
                if (!pConfigInfo) {
                    ERR("OOM while supplying DRVCONFIGINFO for DRV_CONFIGURE, using NULL\n");
                } else {
                    static const WCHAR drivers32[] = {'D','r','i','v','e','r','s','3','2','\0'};

                    pConfigInfo->dwDCISize = iStructSize;

                    section_name = HeapAlloc(MSACM_hHeap, 0, (strlenW(drivers32) + 1) * sizeof(WCHAR));
                    if (section_name) strcpyW(section_name, drivers32);
                    pConfigInfo->lpszDCISectionName = section_name;
                    alias_name = HeapAlloc(MSACM_hHeap, 0, (strlenW(pAlias) + 1) * sizeof(WCHAR));
                    if (alias_name) strcpyW(alias_name, pAlias);
                    pConfigInfo->lpszDCIAliasName = alias_name;

                    if (pConfigInfo->lpszDCISectionName == NULL || pConfigInfo->lpszDCIAliasName == NULL) {
                        HeapFree(MSACM_hHeap, 0, alias_name);
                        HeapFree(MSACM_hHeap, 0, section_name);
                        HeapFree(MSACM_hHeap, 0, pConfigInfo);
                        pConfigInfo = NULL;
                        ERR("OOM while supplying DRVCONFIGINFO for DRV_CONFIGURE, using NULL\n");
                    }
                }
            }
            
            lParam2 = (LPARAM)pConfigInfo;
        }
        
        if (padid) {
            /* Handle is really an HACMDRIVERID, must have an open session to get an HACMDRIVER */
            if (padid->pACMDriverList != NULL) {
                lResult = MSACM_Message((HACMDRIVER)padid->pACMDriverList, uMsg, lParam1, lParam2);
            } else {
                MMRESULT mmr = acmDriverOpen(&had, (HACMDRIVERID)padid, 0);
                if (mmr != MMSYSERR_NOERROR) {
                    lResult = MMSYSERR_INVALPARAM;
                } else {
                    lResult = acmDriverMessage(had, uMsg, lParam1, lParam2);
                    acmDriverClose(had, 0);
                }
            }
        } else {
            lResult = MSACM_Message(had, uMsg, lParam1, lParam2);
        }
        if (pConfigInfo) {
            HeapFree(MSACM_hHeap, 0, alias_name);
            HeapFree(MSACM_hHeap, 0, section_name);
            HeapFree(MSACM_hHeap, 0, pConfigInfo);
        }
        return lResult;
    }
    WARN("invalid parameter\n");
    return MMSYSERR_INVALPARAM;
}
Esempio n. 19
0
static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid,
                                    DWORD_PTR dwInstance,
                                    DWORD fdwSupport)
{
    MMRESULT rc;
    ACMDRIVERDETAILSA dd;
    HACMDRIVER had;

    DWORD dwDriverPriority;
    DWORD dwDriverSupport;

    if (winetest_interactive) {
        trace("id: %p\n", hadid);
        trace("  Supports:\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_ASYNC)
            trace("    async conversions\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC)
            trace("    different format conversions\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER)
            trace("    same format conversions\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER)
            trace("    filtering\n");
    }

    /* try an invalid pointer */
    rc = acmDriverDetailsA(hadid, 0, 0);
    ok(rc == MMSYSERR_INVALPARAM,
       "acmDriverDetailsA(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALPARAM);

    /* try an invalid structure size */
    ZeroMemory(&dd, sizeof(dd));
    rc = acmDriverDetailsA(hadid, &dd, 0);
    ok(rc == MMSYSERR_INVALPARAM,
       "acmDriverDetailsA(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALPARAM);

    /* MSDN says this should fail but it doesn't in practice */
    dd.cbStruct = 4;
    rc = acmDriverDetailsA(hadid, &dd, 0);
    ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NOTSUPPORTED,
       "acmDriverDetailsA(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_NOERROR);

    /* try an invalid handle */
    dd.cbStruct = sizeof(dd);
    rc = acmDriverDetailsA((HACMDRIVERID)1, &dd, 0);
    ok(rc == MMSYSERR_INVALHANDLE,
       "acmDriverDetailsA(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALHANDLE);

    /* try an invalid handle and pointer */
    rc = acmDriverDetailsA((HACMDRIVERID)1, 0, 0);
    ok(rc == MMSYSERR_INVALPARAM,
       "acmDriverDetailsA(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALPARAM);

    /* try invalid details */
    rc = acmDriverDetailsA(hadid, &dd, -1);
    ok(rc == MMSYSERR_INVALFLAG,
       "acmDriverDetailsA(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALFLAG);

    /* try valid parameters */
    rc = acmDriverDetailsA(hadid, &dd, 0);
    ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NOTSUPPORTED,
       "acmDriverDetailsA(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_NOERROR);

    /* cbStruct should contain size of returned data (at most sizeof(dd))
       TODO: should it be *exactly* sizeof(dd), as tested here?
     */
    if (rc == MMSYSERR_NOERROR) {
        static const struct {
            const char *shortname;
            WORD mid;
            WORD pid;
            WORD pid_alt;
        } *iter, expected_ids[] = {
            { "Microsoft IMA ADPCM", MM_MICROSOFT, MM_MSFT_ACM_IMAADPCM },
            { "MS-ADPCM", MM_MICROSOFT, MM_MSFT_ACM_MSADPCM },
            { "Microsoft CCITT G.711", MM_MICROSOFT, MM_MSFT_ACM_G711},
            { "MPEG Layer-3 Codec", MM_FRAUNHOFER_IIS, MM_FHGIIS_MPEGLAYER3_DECODE, MM_FHGIIS_MPEGLAYER3_PROFESSIONAL },
            { "MS-PCM", MM_MICROSOFT, MM_MSFT_ACM_PCM },
            { 0 }
        };

        ok(dd.cbStruct == sizeof(dd),
           "acmDriverDetailsA(): cbStruct = %08x\n", dd.cbStruct);

        for (iter = expected_ids; iter->shortname; ++iter) {
            if (!strcmp(iter->shortname, dd.szShortName)) {
                /* try alternative product id on mismatch */
                if (iter->pid_alt && iter->pid != dd.wPid)
                    ok(iter->mid == dd.wMid && iter->pid_alt == dd.wPid,
                       "Got wrong manufacturer (0x%x vs 0x%x) or product (0x%x vs 0x%x)\n",
                       dd.wMid, iter->mid,
                       dd.wPid, iter->pid_alt);
                else
                    ok(iter->mid == dd.wMid && iter->pid == dd.wPid,
                       "Got wrong manufacturer (0x%x vs 0x%x) or product (0x%x vs 0x%x)\n",
                       dd.wMid, iter->mid,
                       dd.wPid, iter->pid);
            }
        }
    }

    if (rc == MMSYSERR_NOERROR && winetest_interactive) {
        trace("  Short name: %s\n", dd.szShortName);
        trace("  Long name: %s\n", dd.szLongName);
        trace("  Copyright: %s\n", dd.szCopyright);
        trace("  Licensing: %s\n", dd.szLicensing);
        trace("  Features: %s\n", dd.szFeatures);
        trace("  Supports %u formats\n", dd.cFormatTags);
        trace("  Supports %u filter formats\n", dd.cFilterTags);
        trace("  Mid: 0x%x\n", dd.wMid);
        trace("  Pid: 0x%x\n", dd.wPid);
    }

    /* try bad pointer */
    rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, 0);
    ok(rc == MMSYSERR_INVALPARAM,
       "acmMetrics(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALPARAM);

    /* try bad handle */
    rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, &dwDriverPriority);
    ok(rc == MMSYSERR_INVALHANDLE,
       "acmMetrics(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALHANDLE);

    /* try bad pointer and handle */
    rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, 0);
    ok(rc == MMSYSERR_INVALHANDLE,
       "acmMetrics(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALHANDLE);

    /* try valid parameters */
    rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, &dwDriverSupport);
    ok(rc == MMSYSERR_NOERROR,
       "acmMetrics(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_NOERROR);

    /* try bad pointer */
    rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, 0);
    ok(rc == MMSYSERR_INVALPARAM,
       "acmMetrics(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALPARAM);

    /* try bad handle */
    rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport);
    ok(rc == MMSYSERR_INVALHANDLE,
       "acmMetrics(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALHANDLE);

    /* try bad pointer and handle */
    rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, 0);
    ok(rc == MMSYSERR_INVALHANDLE,
       "acmMetrics(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALHANDLE);

    /* try valid parameters */
    rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport);
    ok(rc == MMSYSERR_NOERROR,
       "acmMetrics(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_NOERROR);

    /* try invalid pointer */
    rc = acmDriverOpen(0, hadid, 0);
    ok(rc == MMSYSERR_INVALPARAM,
       "acmDriverOpen(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALPARAM);

    /* try invalid handle */
    rc = acmDriverOpen(&had, (HACMDRIVERID)1, 0);
    ok(rc == MMSYSERR_INVALHANDLE,
       "acmDriverOpen(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALHANDLE);

    /* try invalid open */
    rc = acmDriverOpen(&had, hadid, -1);
    ok(rc == MMSYSERR_INVALFLAG,
       "acmDriverOpen(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALFLAG);

    /* try valid parameters */
    rc = acmDriverOpen(&had, hadid, 0);
    ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NODRIVER,
       "acmDriverOpen(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_NOERROR);

    if (rc == MMSYSERR_NOERROR) {
        DWORD dwSize;
        HACMDRIVERID hid;

        /* try bad pointer */
        rc = acmDriverID((HACMOBJ)had, 0, 0);
        ok(rc == MMSYSERR_INVALPARAM,
           "acmDriverID(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALPARAM);

        /* try bad handle */
        rc = acmDriverID((HACMOBJ)1, &hid, 0);
        ok(rc == MMSYSERR_INVALHANDLE,
           "acmDriverID(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALHANDLE);

        /* try bad handle and pointer */
        rc = acmDriverID((HACMOBJ)1, 0, 0);
        ok(rc == MMSYSERR_INVALHANDLE,
           "acmDriverID(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALHANDLE);

        /* try bad flag */
        rc = acmDriverID((HACMOBJ)had, &hid, 1);
        ok(rc == MMSYSERR_INVALFLAG,
           "acmDriverID(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALFLAG);

        /* try valid parameters */
        rc = acmDriverID((HACMOBJ)had, &hid, 0);
        ok(rc == MMSYSERR_NOERROR,
           "acmDriverID(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_NOERROR);
        ok(hid == hadid,
           "acmDriverID() returned ID %p doesn't equal %p\n",
           hid, hadid);

        /* try bad pointer */
        rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, 0);
        ok(rc == MMSYSERR_INVALPARAM,
           "acmMetrics(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALPARAM);

        /* try bad handle */
        rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
        ok(rc == MMSYSERR_INVALHANDLE,
           "acmMetrics(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALHANDLE);

        /* try bad pointer and handle */
        rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, 0);
        ok(rc == MMSYSERR_INVALHANDLE,
           "acmMetrics(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALHANDLE);

        /* try valid parameters */
        rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
        ok(rc == MMSYSERR_NOERROR,
           "acmMetrics(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_NOERROR);
        if (rc == MMSYSERR_NOERROR) {
            ACMFORMATDETAILSA fd;
            WAVEFORMATEX * pwfx;
            ACMFORMATTAGDETAILSA aftd;

            /* try bad pointer */
            rc = acmFormatEnumA(had, 0, FormatEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatEnumA(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALPARAM);

            /* try bad structure size */
            ZeroMemory(&fd, sizeof(fd));
            rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatEnumA(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALPARAM);

            fd.cbStruct = sizeof(fd) - 1;
            rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatEnumA(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALPARAM);

            if (dwSize < sizeof(WAVEFORMATEX))
                dwSize = sizeof(WAVEFORMATEX);

            pwfx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);

            pwfx->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
            pwfx->wFormatTag = WAVE_FORMAT_UNKNOWN;

            fd.cbStruct = sizeof(fd);
            fd.pwfx = pwfx;
            fd.cbwfx = dwSize;
            fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;

            /* try valid parameters */
            rc = acmFormatEnumA(had, &fd, FormatEnumProc, 0, 0);
            ok(rc == MMSYSERR_NOERROR,
               "acmFormatEnumA(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_NOERROR);

            /* try bad pointer */
            rc = acmFormatTagEnumA(had, 0, FormatTagEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALPARAM);

            /* try bad structure size */
            ZeroMemory(&aftd, sizeof(aftd));
            rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALPARAM);

            aftd.cbStruct = sizeof(aftd) - 1;
            rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALPARAM);

            aftd.cbStruct = sizeof(aftd);
            aftd.dwFormatTag = WAVE_FORMAT_UNKNOWN;

            /* try bad flag */
            rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 1);
            ok(rc == MMSYSERR_INVALFLAG,
               "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALFLAG);

            /* try valid parameters */
            rc = acmFormatTagEnumA(had, &aftd, FormatTagEnumProc, 0, 0);
            ok(rc == MMSYSERR_NOERROR,
               "acmFormatTagEnumA(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_NOERROR);

            HeapFree(GetProcessHeap(), 0, pwfx);

            /* try invalid handle */
            rc = acmDriverClose((HACMDRIVER)1, 0);
            ok(rc == MMSYSERR_INVALHANDLE,
               "acmDriverClose(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALHANDLE);

            /* try invalid flag */
            rc = acmDriverClose(had, 1);
            ok(rc == MMSYSERR_INVALFLAG,
               "acmDriverClose(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALFLAG);

            /* try valid parameters */
            rc = acmDriverClose(had, 0);
            ok(rc == MMSYSERR_NOERROR,
               "acmDriverClose(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_NOERROR);

            /* try closing again */
            rc = acmDriverClose(had, 0);
            ok(rc == MMSYSERR_INVALHANDLE,
               "acmDriverClose(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALHANDLE);
        }
    }

    return TRUE;
}
Esempio n. 20
0
bool VDAudioCodecW32::Init(const WAVEFORMATEX *pSrcFormat, const WAVEFORMATEX *pDstFormat, bool isCompression, const char *pDriverShortNameHint, bool throwOnError) {
	Shutdown();

	SafeCopyWaveFormat(mSrcFormat, (const VDWaveFormat *)pSrcFormat);

	if (pDstFormat)
		SafeCopyWaveFormat(mDstFormat, (const VDWaveFormat *)pDstFormat);

	// enumerate IDs for all installed codecs
	ACMDriverList driverList(pDriverShortNameHint);

	// try one driver at a time
	MMRESULT res = 0;

	for(ACMDriverList::const_iterator it(driverList.begin()), itEnd(driverList.end());
		it != itEnd;
		++it)
	{
		const HACMDRIVERID driverId = *it;

		// open driver
		HACMDRIVER hDriver = NULL;
		if (acmDriverOpen(&hDriver, *it, 0))
			continue;

		if (!pDstFormat) {
			VDASSERT(!isCompression);
		
			DWORD dwDstFormatSize = 0;

			VDVERIFY(!acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, (LPVOID)&dwDstFormatSize));

			if (dwDstFormatSize < sizeof(WAVEFORMATEX))
				dwDstFormatSize = sizeof(WAVEFORMATEX);

			mDstFormat.resize(dwDstFormatSize);
			memset(mDstFormat.data(), 0, dwDstFormatSize);
			mDstFormat->mTag = WAVE_FORMAT_PCM;

			if (acmFormatSuggest(hDriver, (WAVEFORMATEX *)pSrcFormat, (WAVEFORMATEX *)mDstFormat.data(), dwDstFormatSize, ACM_FORMATSUGGESTF_WFORMATTAG)) {
				acmDriverClose(hDriver, NULL);
				continue;
			}

			// sanitize the destination format a bit

			if (mDstFormat->mSampleBits != 8 && mDstFormat->mSampleBits != 16)
				mDstFormat->mSampleBits = 16;

			if (mDstFormat->mChannels != 1 && mDstFormat->mChannels !=2)
				mDstFormat->mChannels = 2;

			mDstFormat->mBlockSize		= (uint16)((mDstFormat->mSampleBits >> 3) * mDstFormat->mChannels);
			mDstFormat->mDataRate		= mDstFormat->mBlockSize * mDstFormat->mSamplingRate;
			mDstFormat->mExtraSize		= 0;
			mDstFormat.resize(sizeof(WAVEFORMATEX));
		}

		// open conversion stream
		res = acmStreamOpen(&mhStream, hDriver, (WAVEFORMATEX *)pSrcFormat, (WAVEFORMATEX *)mDstFormat.data(), NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME);
		if (!res) {
			mhDriver = hDriver;
			break;
		}

		// Aud-X accepts PCM/6ch but not WAVE_FORMAT_EXTENSIBLE/PCM/6ch. Argh. We attempt to work
		// around this by trying a PCM version if WFE doesn't work.
		if (isCompression) {
			// Need to put this somewhere.
			struct WaveFormatExtensibleW32 {
				WAVEFORMATEX mFormat;
				union {
					uint16 mBitDepth;
					uint16 mSamplesPerBlock;		// may be zero, according to MSDN
				};
				uint32	mChannelMask;
				GUID	mGuid;
			};

			static const GUID local_KSDATAFORMAT_SUBTYPE_PCM={	// so we don't have to bring in ksmedia.h
				WAVE_FORMAT_PCM, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
			};

			if (pSrcFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE && pSrcFormat->cbSize >= sizeof(WaveFormatExtensibleW32) - sizeof(WAVEFORMATEX)) {
				const WaveFormatExtensibleW32& wfexex = *(const WaveFormatExtensibleW32 *)pSrcFormat;

				if (wfexex.mGuid == local_KSDATAFORMAT_SUBTYPE_PCM) {
					// Rewrite the format to be straight PCM and try again.
					vdstructex<VDWaveFormat> srcFormat2(mSrcFormat.data(), sizeof(VDWaveFormat));
					srcFormat2->mExtraSize	= 0;
					srcFormat2->mTag		= WAVE_FORMAT_PCM;
					MMRESULT res2 = acmStreamOpen(&mhStream, hDriver, (WAVEFORMATEX *)srcFormat2.data(), (WAVEFORMATEX *)mDstFormat.data(), NULL, 0, 0, ACM_STREAMOPENF_NONREALTIME);

					if (!res2) {
						res = res2;
						mSrcFormat = srcFormat2;
						pSrcFormat = (WAVEFORMATEX *)mSrcFormat.data();

						mhDriver = hDriver;
						break;
					}
				}
			}
		}

		acmDriverClose(hDriver, 0);
	}
Esempio n. 21
0
/***********************************************************************
 *           acmStreamOpen (MSACM32.40)
 */
MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
			      PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
			      DWORD dwInstance, DWORD fdwOpen)
{
    PWINE_ACMSTREAM	was;
    PWINE_ACMDRIVER	wad;
    MMRESULT		ret;
    int			wfxSrcSize;
    int			wfxDstSize;
    
    TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
	  phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);

    TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", 
	  pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec, 
	  pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);

    TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", 
	  pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec, 
	  pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);

#define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
    wfxSrcSize = SIZEOF_WFX(pwfxSrc);
    wfxDstSize = SIZEOF_WFX(pwfxDst);
#undef SIZEOF_WFX

    was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
    if (was == NULL)
	return MMSYSERR_NOMEM;
    was->drvInst.cbStruct = sizeof(was->drvInst);
    was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
    memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
    // LHACM is checking for 0x1
    // but if this will not help
    // was->drvInst.pwfxSrc->wFormatTag = 1;
    was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
    memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
    if (pwfltr) {
	was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
	memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
    } else {
	was->drvInst.pwfltr = NULL;
    }
    was->drvInst.dwCallback = dwCallback;    
    was->drvInst.dwInstance = dwInstance;
    was->drvInst.fdwOpen = fdwOpen;
    was->drvInst.fdwDriver = 0L;  
    was->drvInst.dwDriver = 0L;     
    was->drvInst.has = (HACMSTREAM)was;
    
    if (had) {
	if (!(wad = MSACM_GetDriver(had))) {
	    ret = MMSYSERR_INVALPARAM;
	    goto errCleanUp;
	}
	
	was->obj.pACMDriverID = wad->obj.pACMDriverID;
	was->pDrv = wad;
	was->hAcmDriver = 0; /* not to close it in acmStreamClose */

	ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
	if (ret != MMSYSERR_NOERROR)
	    goto errCleanUp;
    } else {
	PWINE_ACMDRIVERID wadi;
	/* short drv_tag; -- not used */
	ret = ACMERR_NOTPOSSIBLE;
/*	if(pwfxSrc->wFormatTag==1)//compression
	    drv_tag=pwfxDst->wFormatTag;
	    else
	    if(pwfxDst->wFormatTag==1)//decompression
		drv_tag=pwfxSrc->wFormatTag;
		else
		goto errCleanUp;

	    ret=acmDriverOpen2(drv_tag); 
	    if (ret == MMSYSERR_NOERROR) {
		if ((wad = MSACM_GetDriver(had)) != 0) {
		    was->obj.pACMDriverID = wad->obj.pACMDriverID;
		    was->pDrv = wad;
		    was->hAcmDriver = had;
		    
		    ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
		    if (ret == MMSYSERR_NOERROR) {
			if (fdwOpen & ACM_STREAMOPENF_QUERY) {
			    acmDriverClose(had, 0L);
			}
			break;
		    }
		}
		acmDriverClose(had, 0L);*/
	//if(MSACM_pFirstACMDriverID==NULL)
	//    MSACM_RegisterAllDrivers();
	
	for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID)
	{
	    /* Check Format */
	    if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue;

	    ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
	    if (ret == MMSYSERR_NOERROR) {
		if ((wad = MSACM_GetDriver(had)) != 0) {
		    was->obj.pACMDriverID = wad->obj.pACMDriverID;
		    was->pDrv = wad;
		    was->hAcmDriver = had;
		    
		    ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
		    //lhacm - crash printf("RETOPEN %d\n", ret);
                    //ret = 0;
		    if (ret == MMSYSERR_NOERROR) {
			if (fdwOpen & ACM_STREAMOPENF_QUERY) {
			    acmDriverClose(had, 0L);
			}
			break;
		    }
		}
		// no match, close this acm driver and try next one 
		acmDriverClose(had, 0L);
	    }
	}
	if (ret != MMSYSERR_NOERROR) {
	    ret = ACMERR_NOTPOSSIBLE;
	    goto errCleanUp;
	}
    }
    ret = MMSYSERR_NOERROR;
    if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
	if (phas)
	    *phas = (HACMSTREAM)was;
	TRACE("=> (%d)\n", ret);
	CodecAlloc();
	return ret;
    }
errCleanUp:		
    if (phas)
	*phas = (HACMSTREAM)0;
    HeapFree(MSACM_hHeap, 0, was);
    TRACE("=> (%d)\n", ret);
    return ret;
}
Esempio n. 22
0
static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid,
                                    DWORD_PTR dwInstance,
                                    DWORD fdwSupport)
{
    MMRESULT rc;
    ACMDRIVERDETAILS dd;
    HACMDRIVER had;
    
    DWORD dwDriverPriority;
    DWORD dwDriverSupport;

    if (winetest_interactive) {
        trace("id: %p\n", hadid);
        trace("  Supports:\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_ASYNC)
            trace("    async conversions\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC)
            trace("    different format conversions\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER)
            trace("    same format conversions\n");
        if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER)
            trace("    filtering\n");
    }

    /* try an invalid pointer */
    rc = acmDriverDetails(hadid, 0, 0);
    ok(rc == MMSYSERR_INVALPARAM,
       "acmDriverDetails(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALPARAM);

    /* try an invalid structure size */
    ZeroMemory(&dd, sizeof(dd));
    rc = acmDriverDetails(hadid, &dd, 0);
    ok(rc == MMSYSERR_INVALPARAM,
       "acmDriverDetails(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALPARAM);

    /* MSDN says this should fail but it doesn't in practice */
    dd.cbStruct = 4;
    rc = acmDriverDetails(hadid, &dd, 0);
    ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NOTSUPPORTED,
       "acmDriverDetails(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_NOERROR);

    /* try an invalid handle */
    dd.cbStruct = sizeof(dd);
    rc = acmDriverDetails((HACMDRIVERID)1, &dd, 0);
    ok(rc == MMSYSERR_INVALHANDLE,
       "acmDriverDetails(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALHANDLE);

    /* try an invalid handle and pointer */
    rc = acmDriverDetails((HACMDRIVERID)1, 0, 0);
    ok(rc == MMSYSERR_INVALPARAM,
       "acmDriverDetails(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALPARAM);

    /* try invalid details */
    rc = acmDriverDetails(hadid, &dd, -1);
    ok(rc == MMSYSERR_INVALFLAG,
       "acmDriverDetails(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALFLAG);

    /* try valid parameters */
    rc = acmDriverDetails(hadid, &dd, 0);
    ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NOTSUPPORTED,
       "acmDriverDetails(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_NOERROR);

    /* cbStruct should contain size of returned data (at most sizeof(dd)) 
       TODO: should it be *exactly* sizeof(dd), as tested here?
     */
    if (rc == MMSYSERR_NOERROR) {
        ok(dd.cbStruct == sizeof(dd),
            "acmDriverDetails(): cbStruct = %08x\n", dd.cbStruct);
    }

    if (rc == MMSYSERR_NOERROR && winetest_interactive) {
        trace("  Short name: %s\n", dd.szShortName);
        trace("  Long name: %s\n", dd.szLongName);
        trace("  Copyright: %s\n", dd.szCopyright);
        trace("  Licensing: %s\n", dd.szLicensing);
        trace("  Features: %s\n", dd.szFeatures);
        trace("  Supports %u formats\n", dd.cFormatTags);
        trace("  Supports %u filter formats\n", dd.cFilterTags);
    }

    /* try bad pointer */
    rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, 0);
    ok(rc == MMSYSERR_INVALPARAM,
        "acmMetrics(): rc = %08x, should be %08x\n",
        rc, MMSYSERR_INVALPARAM);

    /* try bad handle */
    rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, &dwDriverPriority);
    ok(rc == MMSYSERR_INVALHANDLE,
        "acmMetrics(): rc = %08x, should be %08x\n",
        rc, MMSYSERR_INVALHANDLE);

    /* try bad pointer and handle */
    rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, 0);
    ok(rc == MMSYSERR_INVALHANDLE,
        "acmMetrics(): rc = %08x, should be %08x\n",
        rc, MMSYSERR_INVALHANDLE);

    /* try valid parameters */
    rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, &dwDriverSupport);
    ok(rc == MMSYSERR_NOERROR,
        "acmMetrics(): rc = %08x, should be %08x\n",
        rc, MMSYSERR_NOERROR);

    /* try bad pointer */
    rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, 0);
    ok(rc == MMSYSERR_INVALPARAM,
        "acmMetrics(): rc = %08x, should be %08x\n",
        rc, MMSYSERR_INVALPARAM);

    /* try bad handle */
    rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport);
    ok(rc == MMSYSERR_INVALHANDLE,
        "acmMetrics(): rc = %08x, should be %08x\n",
        rc, MMSYSERR_INVALHANDLE);

    /* try bad pointer and handle */
    rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, 0);
    ok(rc == MMSYSERR_INVALHANDLE,
        "acmMetrics(): rc = %08x, should be %08x\n",
        rc, MMSYSERR_INVALHANDLE);

    /* try valid parameters */
    rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport);
    ok(rc == MMSYSERR_NOERROR,
        "acmMetrics(): rc = %08x, should be %08x\n",
        rc, MMSYSERR_NOERROR);

    /* try invalid pointer */
    rc = acmDriverOpen(0, hadid, 0);
    ok(rc == MMSYSERR_INVALPARAM,
       "acmDriverOpen(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALPARAM);

    /* try invalid handle */
    rc = acmDriverOpen(&had, (HACMDRIVERID)1, 0);
    ok(rc == MMSYSERR_INVALHANDLE,
       "acmDriverOpen(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALHANDLE);

    /* try invalid open */
    rc = acmDriverOpen(&had, hadid, -1);
    ok(rc == MMSYSERR_INVALFLAG,
       "acmDriverOpen(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_INVALFLAG);

    /* try valid parameters */
    rc = acmDriverOpen(&had, hadid, 0);
    ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_NODRIVER,
       "acmDriverOpen(): rc = %08x, should be %08x\n",
       rc, MMSYSERR_NOERROR);

    if (rc == MMSYSERR_NOERROR) {
        DWORD dwSize;
        HACMDRIVERID hid;

        /* try bad pointer */
        rc = acmDriverID((HACMOBJ)had, 0, 0);
        ok(rc == MMSYSERR_INVALPARAM,
           "acmDriverID(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALPARAM);

        /* try bad handle */
        rc = acmDriverID((HACMOBJ)1, &hid, 0);
        ok(rc == MMSYSERR_INVALHANDLE,
           "acmDriverID(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALHANDLE);

        /* try bad handle and pointer */
        rc = acmDriverID((HACMOBJ)1, 0, 0);
        ok(rc == MMSYSERR_INVALHANDLE,
           "acmDriverID(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALHANDLE);

        /* try bad flag */
        rc = acmDriverID((HACMOBJ)had, &hid, 1);
        ok(rc == MMSYSERR_INVALFLAG,
           "acmDriverID(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALFLAG);

        /* try valid parameters */
        rc = acmDriverID((HACMOBJ)had, &hid, 0);
        ok(rc == MMSYSERR_NOERROR,
           "acmDriverID(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_NOERROR);
        ok(hid == hadid,
           "acmDriverID() returned ID %p doesn't equal %p\n",
           hid, hadid);

        /* try bad pointer */
        rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, 0);
        ok(rc == MMSYSERR_INVALPARAM,
           "acmMetrics(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALPARAM);

        /* try bad handle */
        rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
        ok(rc == MMSYSERR_INVALHANDLE,
           "acmMetrics(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALHANDLE);

        /* try bad pointer and handle */
        rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, 0);
        ok(rc == MMSYSERR_INVALHANDLE,
           "acmMetrics(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_INVALHANDLE);

        /* try valid parameters */
        rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
        ok(rc == MMSYSERR_NOERROR,
           "acmMetrics(): rc = %08x, should be %08x\n",
           rc, MMSYSERR_NOERROR);
        if (rc == MMSYSERR_NOERROR) {
            ACMFORMATDETAILS fd;
            WAVEFORMATEX * pwfx;
            ACMFORMATTAGDETAILS aftd;

            /* try bad pointer */
            rc = acmFormatEnum(had, 0, FormatEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatEnum(): rc = %08x, should be %08x\n",
                rc, MMSYSERR_INVALPARAM);

            /* try bad structure size */
            ZeroMemory(&fd, sizeof(fd));
            rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatEnum(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALPARAM);

            fd.cbStruct = sizeof(fd) - 1;
            rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatEnum(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALPARAM);

            if (dwSize < sizeof(WAVEFORMATEX))
                dwSize = sizeof(WAVEFORMATEX);

            pwfx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);

            pwfx->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
            pwfx->wFormatTag = WAVE_FORMAT_UNKNOWN;

            fd.cbStruct = sizeof(fd);
            fd.pwfx = pwfx;
            fd.cbwfx = dwSize;
            fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;

            /* try valid parameters */
            rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
            ok(rc == MMSYSERR_NOERROR,
               "acmFormatEnum(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_NOERROR);

            /* try bad pointer */
            rc = acmFormatTagEnum(had, 0, FormatTagEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatTagEnum(): rc = %08x, should be %08x\n",
                rc, MMSYSERR_INVALPARAM);

            /* try bad structure size */
            ZeroMemory(&aftd, sizeof(aftd));
            rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatTagEnum(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALPARAM);

            aftd.cbStruct = sizeof(aftd) - 1;
            rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
            ok(rc == MMSYSERR_INVALPARAM,
               "acmFormatTagEnum(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALPARAM);

            aftd.cbStruct = sizeof(aftd);
            aftd.dwFormatTag = WAVE_FORMAT_UNKNOWN;

            /* try bad flag */
            rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 1);
            ok(rc == MMSYSERR_INVALFLAG,
               "acmFormatTagEnum(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALFLAG);

            /* try valid parameters */
            rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
            ok(rc == MMSYSERR_NOERROR,
               "acmFormatTagEnum(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_NOERROR);

            HeapFree(GetProcessHeap(), 0, pwfx);

            /* try invalid handle */
            rc = acmDriverClose((HACMDRIVER)1, 0);
            ok(rc == MMSYSERR_INVALHANDLE,
               "acmDriverClose(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALHANDLE);

            /* try invalid flag */
            rc = acmDriverClose(had, 1);
            ok(rc == MMSYSERR_INVALFLAG,
               "acmDriverClose(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALFLAG);

            /* try valid parameters */
            rc = acmDriverClose(had, 0);
            ok(rc == MMSYSERR_NOERROR,
               "acmDriverClose(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_NOERROR);

            /* try closing again */
            rc = acmDriverClose(had, 0);
            ok(rc == MMSYSERR_INVALHANDLE,
               "acmDriverClose(): rc = %08x, should be %08x\n",
               rc, MMSYSERR_INVALHANDLE);
        }
    }

    return TRUE;
}