⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mci.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
	    }
	} else {
	    dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
	}
    }
    return dwRet;
}

/**************************************************************************
 * 			MCI_Open				[internal]
 */
static	DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSW lpParms)
{
    WCHAR			strDevTyp[128];
    DWORD 			dwRet;
    LPWINE_MCIDRIVER		wmd = NULL;

    TRACE("(%08lX, %p)\n", dwParam, lpParms);
    if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;

    /* only two low bytes are generic, the other ones are dev type specific */
#define WINE_MCIDRIVER_SUPP	(0xFFFF0000|MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT| \
                         MCI_OPEN_ALIAS|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID| \
                         MCI_NOTIFY|MCI_WAIT)
    if ((dwParam & ~WINE_MCIDRIVER_SUPP) != 0) {
	FIXME("Unsupported yet dwFlags=%08lX\n", dwParam & ~WINE_MCIDRIVER_SUPP);
    }
#undef WINE_MCIDRIVER_SUPP

    strDevTyp[0] = 0;

    if (dwParam & MCI_OPEN_TYPE) {
	if (dwParam & MCI_OPEN_TYPE_ID) {
	    WORD uDevType = LOWORD((DWORD)lpParms->lpstrDeviceType);

	    if (uDevType < MCI_DEVTYPE_FIRST ||
		uDevType > MCI_DEVTYPE_LAST ||
		!LoadStringW(WINMM_IData.hWinMM32Instance, uDevType, 
                             strDevTyp, sizeof(strDevTyp) / sizeof(WCHAR))) {
		dwRet = MCIERR_BAD_INTEGER;
		goto errCleanUp;
	    }
	} else {
	    LPWSTR	ptr;
	    if (lpParms->lpstrDeviceType == NULL) {
		dwRet = MCIERR_NULL_PARAMETER_BLOCK;
		goto errCleanUp;
	    }
	    strcpyW(strDevTyp, lpParms->lpstrDeviceType);
	    ptr = strchrW(strDevTyp, '!');
	    if (ptr) {
		/* this behavior is not documented in windows. However, since, in
		 * some occasions, MCI_OPEN handling is translated by WinMM into
		 * a call to mciSendString("open <type>"); this code shall be correct
		 */
		if (dwParam & MCI_OPEN_ELEMENT) {
		    ERR("Both MCI_OPEN_ELEMENT(%s) and %s are used\n",
			debugstr_w(lpParms->lpstrElementName), 
                        debugstr_w(strDevTyp));
		    dwRet = MCIERR_UNRECOGNIZED_KEYWORD;
		    goto errCleanUp;
		}
		dwParam |= MCI_OPEN_ELEMENT;
		*ptr++ = 0;
		/* FIXME: not a good idea to write in user supplied buffer */
		lpParms->lpstrElementName = ptr;
	    }

	}
	TRACE("devType=%s !\n", debugstr_w(strDevTyp));
    }

    if (dwParam & MCI_OPEN_ELEMENT) {
	TRACE("lpstrElementName=%s\n", debugstr_w(lpParms->lpstrElementName));

	if (dwParam & MCI_OPEN_ELEMENT_ID) {
	    FIXME("Unsupported yet flag MCI_OPEN_ELEMENT_ID\n");
	    dwRet = MCIERR_UNRECOGNIZED_KEYWORD;
	    goto errCleanUp;
	}

	if (!lpParms->lpstrElementName) {
	    dwRet = MCIERR_NULL_PARAMETER_BLOCK;
	    goto errCleanUp;
	}

	/* type, if given as a parameter, supersedes file extension */
	if (!strDevTyp[0] &&
	    MCI_GetDevTypeFromFileName(lpParms->lpstrElementName,
				       strDevTyp, sizeof(strDevTyp))) {
            static const WCHAR wszCdAudio[] = {'C','D','A','U','D','I','O',0};
	    if (GetDriveTypeW(lpParms->lpstrElementName) != DRIVE_CDROM) {
		dwRet = MCIERR_EXTENSION_NOT_FOUND;
		goto errCleanUp;
	    }
	    /* FIXME: this will not work if several CDROM drives are installed on the machine */
	    strcpyW(strDevTyp, wszCdAudio);
	}
    }

    if (strDevTyp[0] == 0) {
	FIXME("Couldn't load driver\n");
	dwRet = MCIERR_INVALID_DEVICE_NAME;
	goto errCleanUp;
    }

    if (dwParam & MCI_OPEN_ALIAS) {
	TRACE("Alias=%s !\n", debugstr_w(lpParms->lpstrAlias));
	if (!lpParms->lpstrAlias) {
	    dwRet = MCIERR_NULL_PARAMETER_BLOCK;
	    goto errCleanUp;
	}
    }

    if ((dwRet = MCI_LoadMciDriver(strDevTyp, &wmd))) {
	goto errCleanUp;
    }

    if ((dwRet = MCI_FinishOpen(wmd, lpParms, dwParam))) {
	TRACE("Failed to open driver (MCI_OPEN_DRIVER) [%08lx], closing\n", dwRet);
	/* FIXME: is dwRet the correct ret code ? */
	goto errCleanUp;
    }

    /* only handled devices fall through */
    TRACE("wDevID=%04X wDeviceID=%d dwRet=%ld\n", wmd->wDeviceID, lpParms->wDeviceID, dwRet);

    if (dwParam & MCI_NOTIFY)
	mciDriverNotify((HWND)lpParms->dwCallback, wmd->wDeviceID, MCI_NOTIFY_SUCCESSFUL);

    return 0;
errCleanUp:
    if (wmd) MCI_UnLoadMciDriver(wmd);

    if (dwParam & MCI_NOTIFY)
	mciDriverNotify((HWND)lpParms->dwCallback, 0, MCI_NOTIFY_FAILURE);
    return dwRet;
}

/**************************************************************************
 * 			MCI_Close				[internal]
 */
static	DWORD MCI_Close(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
{
    DWORD		dwRet;
    LPWINE_MCIDRIVER	wmd;

    TRACE("(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms);

    if (wDevID == MCI_ALL_DEVICE_ID) {
	LPWINE_MCIDRIVER	next;

	EnterCriticalSection(&WINMM_IData.cs);
	/* FIXME: shall I notify once after all is done, or for
	 * each of the open drivers ? if the latest, which notif
	 * to return when only one fails ?
	 */
	for (wmd = WINMM_IData.lpMciDrvs; wmd; ) {
	    next = wmd->lpNext;
	    MCI_Close(wmd->wDeviceID, dwParam, lpParms);
	    wmd = next;
	}
	LeaveCriticalSection(&WINMM_IData.cs);
	return 0;
    }

    if (!(wmd = MCI_GetDriver(wDevID))) {
	return MCIERR_INVALID_DEVICE_ID;
    }

    dwRet = MCI_SendCommandFrom32(wDevID, MCI_CLOSE_DRIVER, dwParam, (DWORD)lpParms);

    MCI_UnLoadMciDriver(wmd);

    if (dwParam & MCI_NOTIFY)
	mciDriverNotify((HWND)lpParms->dwCallback, wDevID,
                        (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);

    return dwRet;
}

/**************************************************************************
 * 			MCI_WriteString				[internal]
 */
DWORD	MCI_WriteString(LPWSTR lpDstStr, DWORD dstSize, LPCWSTR lpSrcStr)
{
    DWORD	ret = 0;

    if (lpSrcStr) {
        dstSize /= sizeof(WCHAR);
	if (dstSize <= strlenW(lpSrcStr)) {
	    lstrcpynW(lpDstStr, lpSrcStr, dstSize - 1);
	    ret = MCIERR_PARAM_OVERFLOW;
	} else {
	    strcpyW(lpDstStr, lpSrcStr);
	}
    } else {
	*lpDstStr = 0;
    }
    return ret;
}

/**************************************************************************
 * 			MCI_Sysinfo				[internal]
 */
static	DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSW lpParms)
{
    DWORD		ret = MCIERR_INVALID_DEVICE_ID, cnt = 0;
    WCHAR		buf[2048], *s = buf, *p;
    LPWINE_MCIDRIVER	wmd;
    HKEY		hKey;

    if (lpParms == NULL)			return MCIERR_NULL_PARAMETER_BLOCK;

    TRACE("(%08x, %08lX, %08lX[num=%ld, wDevTyp=%u])\n",
	  uDevID, dwFlags, (DWORD)lpParms, lpParms->dwNumber, lpParms->wDeviceType);

    switch (dwFlags & ~MCI_SYSINFO_OPEN) {
    case MCI_SYSINFO_QUANTITY:
	if (lpParms->wDeviceType < MCI_DEVTYPE_FIRST || lpParms->wDeviceType > MCI_DEVTYPE_LAST) {
	    if (dwFlags & MCI_SYSINFO_OPEN) {
		TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers\n");
		EnterCriticalSection(&WINMM_IData.cs);
		for (wmd = WINMM_IData.lpMciDrvs; wmd; wmd = wmd->lpNext) {
		    cnt++;
		}
		LeaveCriticalSection(&WINMM_IData.cs);
	    } else {
		TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers\n");
		if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, wszHklmMci,
			  	   0, KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS) {
		    RegQueryInfoKeyW( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
		    RegCloseKey( hKey );
		}
		if (GetPrivateProfileStringW(wszMci, 0, wszNull, buf, sizeof(buf) / sizeof(buf[0]), wszSystemIni))
		    for (s = buf; *s; s += strlenW(s) + 1) cnt++;
	    }
	} else {
	    if (dwFlags & MCI_SYSINFO_OPEN) {
		TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers of type %u\n", lpParms->wDeviceType);
		EnterCriticalSection(&WINMM_IData.cs);
		for (wmd = WINMM_IData.lpMciDrvs; wmd; wmd = wmd->lpNext) {
		    if (wmd->wType == lpParms->wDeviceType) cnt++;
		}
		LeaveCriticalSection(&WINMM_IData.cs);
	    } else {
		TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers of type %u\n", lpParms->wDeviceType);
		FIXME("Don't know how to get # of MCI devices of a given type\n");
		cnt = 1;
	    }
	}
	*(DWORD*)lpParms->lpstrReturn = cnt;
	TRACE("(%ld) => '%ld'\n", lpParms->dwNumber, *(DWORD*)lpParms->lpstrReturn);
	ret = MCI_INTEGER_RETURNED;
	break;
    case MCI_SYSINFO_INSTALLNAME:
	TRACE("MCI_SYSINFO_INSTALLNAME \n");
	if ((wmd = MCI_GetDriver(uDevID))) {
	    ret = MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize,
				  wmd->lpstrDeviceType);
	} else {
	    *lpParms->lpstrReturn = 0;
	    ret = MCIERR_INVALID_DEVICE_ID;
	}
	TRACE("(%ld) => %s\n", lpParms->dwNumber, debugstr_w(lpParms->lpstrReturn));
	break;
    case MCI_SYSINFO_NAME:
	TRACE("MCI_SYSINFO_NAME\n");
	if (dwFlags & MCI_SYSINFO_OPEN) {
	    FIXME("Don't handle MCI_SYSINFO_NAME|MCI_SYSINFO_OPEN (yet)\n");
	    ret = MCIERR_UNRECOGNIZED_COMMAND;
	} else {
	    s = NULL;
	    if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, wszHklmMci, 0, 
                               KEY_QUERY_VALUE, &hKey ) == ERROR_SUCCESS) {
		if (RegQueryInfoKeyW( hKey, 0, 0, 0, &cnt, 
                                      0, 0, 0, 0, 0, 0, 0) == ERROR_SUCCESS && 
                    lpParms->dwNumber <= cnt) {
    		    DWORD bufLen = sizeof(buf);
		    if (RegEnumKeyExW(hKey, lpParms->dwNumber - 1, 
                                      buf, &bufLen, 0, 0, 0, 0) == ERROR_SUCCESS)
                        s = buf;
		}
	        RegCloseKey( hKey );
	    }
	    if (!s) {
		if (GetPrivateProfileStringW(wszMci, 0, wszNull, buf, sizeof(buf) / sizeof(buf[0]), wszSystemIni)) {
		    for (p = buf; *p; p += strlenW(p) + 1, cnt++) {
                        TRACE("%ld: %s\n", cnt, debugstr_w(p));
			if (cnt == lpParms->dwNumber - 1) {
			    s = p;
			    break;
			}
		    }
		}
	    }
	    ret = s ? MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize / sizeof(WCHAR), s) : MCIERR_OUTOFRANGE;
	}
	TRACE("(%ld) => %s\n", lpParms->dwNumber, debugstr_w(lpParms->lpstrReturn));
	break;
    default:
	TRACE("Unsupported flag value=%08lx\n", dwFlags);
	ret = MCIERR_UNRECOGNIZED_COMMAND;
    }
    return ret;
}

/**************************************************************************
 * 			MCI_Break				[internal]
 */
static	DWORD MCI_Break(UINT wDevID, DWORD dwFlags, LPMCI_BREAK_PARMS lpParms)
{
    DWORD	dwRet = 0;

    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;

    if (dwFlags & MCI_NOTIFY)
	mciDriverNotify((HWND)lpParms->dwCallback, wDevID,
                        (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);

    return dwRet;
}

/**************************************************************************
 * 			MCI_Sound				[internal]
 */
static	DWORD MCI_Sound(UINT wDevID, DWORD dwFlags, LPMCI_SOUND_PARMSW lpParms)
{
    DWORD	dwRet = 0;

    if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;

    if (dwFlags & MCI_SOUND_NAME)
        dwRet = sndPlaySoundW(lpParms->lpstrSoundName, SND_SYNC) ? MMSYSERR_NOERROR : MMSYSERR_ERROR;
    else
        dwRet = MMSYSERR_ERROR; /* what should be done ??? */
    if (dwFlags & MCI_NOTIFY)
	mciDriverNotify((HWND)lpParms->dwCallback, wDevID,
                        (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);

    return dwRet;
}

/**************************************************************************
 * 			MCI_SendCommand				[internal]
 */
DWORD	MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD dwParam1,
			DWORD dwParam2, BOOL bFrom32)
{
    DWORD		dwRet = MCIERR_UNRECOGNIZED_COMMAND;

    switch (wMsg) {
    case MCI_OPEN:
	if (bFrom32) {
	    dwRet = MCI_Open(dwParam1, (LPMCI_OPEN_PARMSW)dwParam2);
	} else if (pFnMciMapMsg16To32W) {
	    switch (pFnMciMapMsg16To32W(0, wMsg, dwParam1, &dwParam2)) {
	    case WINMM_MAP_OK:
	    case WINMM_MAP_OKMEM:
		dwRet = MCI_Open(dwParam1, (LPMCI_OPEN_PARMSW)dwParam2);
		pFnMciUnMapMsg16To32W(0, wMsg, dwParam1, dwParam2);
		break;
	    default: break; /* so that gcc does not bark */
	    }
	}
	break;
    case MCI_CLOSE:
	if (bFrom32) {
	    dwRet = MCI_Close(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
	} else if (pFnMciMapMsg16To32W) {
	    switch (pFnMciMapMsg16To32W(0, wMsg, dwParam1, &dwParam2)) {
	    case WINMM_MAP_OK:
	    case WINMM_MAP_OKMEM:
		dwRet = MCI_Close(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
		pFnMciUnMapMsg16To32W(0, wMsg, dwParam1, dwParam2);
		break;
	    default: break; /* so that gcc does not bark */
	    }
	}
	break;
    case MCI_SYSINFO:
	if (bFrom32) {
	    dwRet = MCI_SysInfo(wDevID, dwParam1, (LPMCI_SYSINFO_PARMSW)dwParam2);
	} else if (pFnMciMapMsg16To32W) {
	    switch (pFnMciMapMsg16To32W(0, wMsg, dwParam1, &dwParam2)) {
	    case WINMM_MAP_OK:
	    case WINMM_MAP_OKMEM:
		dwRet = MCI_SysInfo(wDevID, dwParam1, (LPMCI_SYSINFO_PARMSW)dwParam2);
		pFnMciUnMapMsg16To32W(0, wMsg, dwParam1, dwParam2);
		break;
	    default: break; /* so that gcc does not bark */
	    }
	}
	break;
    case MCI_BREAK:
	if (bFrom32) {
	    dwRet = MCI_Break(wDevID, dwParam1, (LPMCI_BREAK_PARMS)dwParam2);
	} else if (pFnMciMapMsg16To32W) {
	    switch (pFnMciMapMsg16To32W(0, wMsg, dwParam1, &dwParam2)) {
	    case WINMM_MAP_OK:
	    ca

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -