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

📄 mci.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
			  LOBYTE(LOWORD(data[1])), HIBYTE(LOWORD(data[1])),
			  LOBYTE(HIWORD(data[1])));
		break;
	    case MCI_COLONIZED4_RETURN:
		snprintfW(lpstrRet, uRetLen, wszCol4,
			  LOBYTE(LOWORD(data[1])), HIBYTE(LOWORD(data[1])),
			  LOBYTE(HIWORD(data[1])), HIBYTE(HIWORD(data[1])));
		break;
	    default:	ERR("Ooops (%04X)\n", HIWORD(dwRet));
	    }
	    break;
	case MCI_STRING:
	    switch (dwRet & 0xFFFF0000ul) {
	    case 0:
		/* nothing to do data[1] == lpstrRet */
		break;
	    case MCI_INTEGER_RETURNED:
		data[1] = *(LPDWORD)lpstrRet;
		snprintfW(lpstrRet, uRetLen, wszLd, data[1]);
		break;
	    default:
		WARN("Oooch. MCI_STRING and HIWORD(dwRet)=%04x\n", HIWORD(dwRet));
		break;
	    }
	    break;
	case MCI_RECT:
	    if (dwRet & 0xFFFF0000ul)
		WARN("Oooch. MCI_STRING and HIWORD(dwRet)=%04x\n", HIWORD(dwRet));
	    snprintfW(lpstrRet, uRetLen, wszLd4,
                      data[1], data[2], data[3], data[4]);
	    break;
	default:		ERR("oops\n");
	}
    }
    return LOWORD(dwRet);
}

/**************************************************************************
 * 				mciSendStringW		[WINMM.@]
 */
DWORD WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrRet,
			    UINT uRetLen, HWND hwndCallback)
{
    LPWSTR		verb, dev, args;
    LPWINE_MCIDRIVER	wmd = 0;
    DWORD		dwFlags = 0, dwRet = 0;
    int			offset = 0;
    DWORD		data[MCI_DATA_SIZE];
    DWORD		retType;
    LPCWSTR		lpCmd = 0;
    LPWSTR		devAlias = NULL;
    BOOL		bAutoOpen = FALSE;
    static const WCHAR  wszNew[] = {'n','e','w',0};
    static const WCHAR  wszSAliasS[] = {' ','a','l','i','a','s',' ',0};

    TRACE("(%s, %p, %d, %p)\n", 
          debugstr_w(lpstrCommand), lpstrRet, uRetLen, hwndCallback);

    /* format is <command> <device> <optargs> */
    if (!(verb = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpstrCommand)+1) * sizeof(WCHAR))))
	return MCIERR_OUT_OF_MEMORY;
    strcpyW( verb, lpstrCommand );
    CharLowerW(verb);

    memset(data, 0, sizeof(data));

    if (!(args = strchrW(verb, ' '))) {
	dwRet = MCIERR_MISSING_DEVICE_NAME;
	goto errCleanUp;
    }
    *args++ = '\0';
    if ((dwRet = MCI_GetString(&dev, &args))) {
	goto errCleanUp;
    }

    /* case dev == 'new' has to be handled */
    if (!strcmpW(dev, wszNew)) {
	FIXME("'new': NIY as device name\n");
	dwRet = MCIERR_MISSING_DEVICE_NAME;
	goto errCleanUp;
    }

    /* otherwise, try to grab devType from open */
    if (!strcmpW(verb, wszOpen)) {
	LPWSTR	devType, tmp;

	if ((devType = strchrW(dev, '!')) != NULL) {
	    *devType++ = '\0';
	    tmp = devType; devType = dev; dev = tmp;

	    dwFlags |= MCI_OPEN_TYPE;
	    data[2] = (DWORD)devType;
	    devType = str_dup_upper(devType);
	    dwFlags |= MCI_OPEN_ELEMENT;
	    data[3] = (DWORD)dev;
	} else if (strchrW(dev, '.') == NULL) {
	    tmp = strchrW(dev,' ');
	    if (tmp) *tmp = '\0';
	    data[2] = (DWORD)dev;
	    devType = str_dup_upper(dev);
	    if (tmp) *tmp = ' ';
	    dwFlags |= MCI_OPEN_TYPE;
	} else {
            static const WCHAR wszTypeS[] = {'t','y','p','e',' ',0};
	    if ((devType = strstrW(args, wszTypeS)) != NULL) {
		devType += 5;
		tmp = strchrW(devType, ' ');
		if (tmp) *tmp = '\0';
		devType = str_dup_upper(devType);
		if (tmp) *tmp = ' ';
		/* dwFlags and data[2] will be correctly set in ParseOpt loop */
	    } else {
		WCHAR	buf[32];
		if ((dwRet = MCI_GetDevTypeFromFileName(dev, buf, sizeof(buf))))
		    goto errCleanUp;

		devType = str_dup_upper(buf);
	    }
	    dwFlags |= MCI_OPEN_ELEMENT;
	    data[3] = (DWORD)dev;
	}
	if ((devAlias = strstrW(args, wszSAliasS))) {
            WCHAR*      tmp2;
	    devAlias += 7;
	    if (!(tmp = strchrW(devAlias,' '))) tmp = devAlias + strlenW(devAlias);
	    if (tmp) *tmp = '\0';
            tmp2 = HeapAlloc(GetProcessHeap(), 0, (tmp - devAlias + 1) * sizeof(WCHAR) );
            memcpy( tmp2, devAlias, (tmp - devAlias) * sizeof(WCHAR) );
            tmp2[tmp - devAlias] = 0;
            data[4] = (DWORD)tmp2;
	    /* should be done in regular options parsing */
	    /* dwFlags |= MCI_OPEN_ALIAS; */
	}

	dwRet = MCI_LoadMciDriver(devType, &wmd);
	if (dwRet == MCIERR_DEVICE_NOT_INSTALLED)
	    dwRet = MCIERR_INVALID_DEVICE_NAME;
	HeapFree(GetProcessHeap(), 0, devType);
	if (dwRet) {
	    MCI_UnLoadMciDriver(wmd);
	    goto errCleanUp;
	}
    } else if (!(wmd = MCI_GetDriver(mciGetDeviceIDW(dev)))) {
	/* auto open */
        static WCHAR wszOpenWait[] = {'o','p','e','n',' ','%','s',' ','w','a','i','t',0};
	WCHAR   buf[128];
	sprintfW(buf, wszOpenWait, dev);

	if ((dwRet = mciSendStringW(buf, NULL, 0, 0)) != 0)
	    goto errCleanUp;

	wmd = MCI_GetDriver(mciGetDeviceIDW(dev));
	if (!wmd) {
	    /* FIXME: memory leak, MCI driver is not closed */
	    dwRet = MCIERR_INVALID_DEVICE_ID;
	    goto errCleanUp;
	}
    }

    /* get the verb in the different command tables */
    if (wmd) {
	/* try the device specific command table */
	lpCmd = MCI_FindCommand(wmd->uSpecificCmdTable, verb);
	if (!lpCmd) {
	    /* try the type specific command table */
	    if (wmd->uTypeCmdTable == MCI_COMMAND_TABLE_NOT_LOADED)
		wmd->uTypeCmdTable = MCI_GetCommandTable(wmd->wType);
	    if (wmd->uTypeCmdTable != MCI_NO_COMMAND_TABLE)
		lpCmd = MCI_FindCommand(wmd->uTypeCmdTable, verb);
	}
    }
    /* try core command table */
    if (!lpCmd) lpCmd = MCI_FindCommand(MCI_GetCommandTable(0), verb);

    if (!lpCmd) {
	TRACE("Command %s not found!\n", debugstr_w(verb));
	dwRet = MCIERR_UNRECOGNIZED_COMMAND;
	goto errCleanUp;
    }

    /* set up call back */
    if (hwndCallback != 0) {
	dwFlags |= MCI_NOTIFY;
	data[0] = (DWORD)hwndCallback;
    }

    /* set return information */
    switch (retType = MCI_GetReturnType(lpCmd)) {
    case 0:		offset = 1;	break;
    case MCI_INTEGER:	offset = 2;	break;
    case MCI_STRING:	data[1] = (DWORD)lpstrRet; data[2] = uRetLen; offset = 3; break;
    case MCI_RECT:	offset = 5;	break;
    default:	ERR("oops\n");
    }

    TRACE("verb=%s on dev=%s; offset=%d\n", 
          debugstr_w(verb), debugstr_w(dev), offset);

    if ((dwRet = MCI_ParseOptArgs(data, offset, lpCmd, args, &dwFlags)))
	goto errCleanUp;

    if (bAutoOpen && (dwFlags & MCI_NOTIFY)) {
	dwRet = MCIERR_NOTIFY_ON_AUTO_OPEN;
	goto errCleanUp;
    }
    /* FIXME: the command should get it's own notification window set up and
     * ask for device closing while processing the notification mechanism
     */
    if (lpstrRet && uRetLen) *lpstrRet = '\0';

    TRACE("[%d, %s, %08lx, %08lx/%s %08lx/%s %08lx/%s %08lx/%s %08lx/%s %08lx/%s]\n",
	  wmd->wDeviceID, MCI_MessageToString(MCI_GetMessage(lpCmd)), dwFlags,
	  data[0], debugstr_w((WCHAR *)data[0]), data[1], debugstr_w((WCHAR *)data[1]),
	  data[2], debugstr_w((WCHAR *)data[2]), data[3], debugstr_w((WCHAR *)data[3]),
	  data[4], debugstr_w((WCHAR *)data[4]), data[5], debugstr_w((WCHAR *)data[5]));

    if (strcmpW(verb, wszOpen) == 0) {
	if ((dwRet = MCI_FinishOpen(wmd, (LPMCI_OPEN_PARMSW)data, dwFlags)))
	    MCI_UnLoadMciDriver(wmd);
	/* FIXME: notification is not properly shared across two opens */
    } else {
	dwRet = MCI_SendCommand(wmd->wDeviceID, MCI_GetMessage(lpCmd), dwFlags, (DWORD)data, TRUE);
    }
    TRACE("=> 1/ %lx (%s)\n", dwRet, debugstr_w(lpstrRet));
    dwRet = MCI_HandleReturnValues(dwRet, wmd, retType, data, lpstrRet, uRetLen);
    TRACE("=> 2/ %lx (%s)\n", dwRet, debugstr_w(lpstrRet));

errCleanUp:
    HeapFree(GetProcessHeap(), 0, verb);
    HeapFree(GetProcessHeap(), 0, devAlias);
    return dwRet;
}

/**************************************************************************
 * 				mciSendStringA			[WINMM.@]
 */
DWORD WINAPI mciSendStringA(LPCSTR lpstrCommand, LPSTR lpstrRet,
			    UINT uRetLen, HWND hwndCallback)
{
    LPWSTR 	lpwstrCommand;
    LPWSTR      lpwstrRet = NULL;
    UINT	ret;
    INT len;

    /* FIXME: is there something to do with lpstrReturnString ? */
    len = MultiByteToWideChar( CP_ACP, 0, lpstrCommand, -1, NULL, 0 );
    lpwstrCommand = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
    MultiByteToWideChar( CP_ACP, 0, lpstrCommand, -1, lpwstrCommand, len );
    if (lpstrRet)
    {
        lpwstrRet = HeapAlloc(GetProcessHeap(), 0, uRetLen * sizeof(WCHAR));
        if (!lpwstrRet) {
            WARN("no memory\n");
            HeapFree( GetProcessHeap(), 0, lpwstrCommand );
            return MCIERR_OUT_OF_MEMORY;
        }
    }
    ret = mciSendStringW(lpwstrCommand, lpwstrRet, uRetLen, hwndCallback);
    if (lpwstrRet)
        WideCharToMultiByte( CP_ACP, 0, lpwstrRet, -1, lpstrRet, uRetLen, NULL, NULL );
    HeapFree(GetProcessHeap(), 0, lpwstrCommand);
    HeapFree(GetProcessHeap(), 0, lpwstrRet);
    return ret;
}

/**************************************************************************
 * 				mciExecute			[WINMM.@]
 * 				mciExecute			[MMSYSTEM.712]
 */
BOOL WINAPI mciExecute(LPCSTR lpstrCommand)
{
    char	strRet[256];
    DWORD	ret;

    TRACE("(%s)!\n", lpstrCommand);

    ret = mciSendStringA(lpstrCommand, strRet, sizeof(strRet), 0);
    if (ret != 0) {
	if (!mciGetErrorStringA(ret, strRet, sizeof(strRet))) {
	    sprintf(strRet, "Unknown MCI error (%ld)", ret);
	}
	MessageBoxA(0, strRet, "Error in mciExecute()", MB_OK);
    }
    /* FIXME: what shall I return ? */
    return TRUE;
}

/**************************************************************************
 *                    	mciLoadCommandResource  		[WINMM.@]
 *
 * Strangely, this function only exists as an UNICODE one.
 */
UINT WINAPI mciLoadCommandResource(HINSTANCE hInst, LPCWSTR resNameW, UINT type)
{
    HRSRC	        hRsrc = 0;
    HGLOBAL      	hMem;
    UINT16		ret = MCI_NO_COMMAND_TABLE;

    TRACE("(%p, %s, %d)!\n", hInst, debugstr_w(resNameW), type);

    /* if a file named "resname.mci" exits, then load resource "resname" from it
     * otherwise directly from driver
     * We don't support it (who uses this feature ?), but we check anyway
     */
    if (!type) {
#if 0
        /* FIXME: we should put this back into order, but I never found a program
         * actually using this feature, so we may not need it
         */
	char		buf[128];
	OFSTRUCT       	ofs;

	strcat(strcpy(buf, resname), ".mci");
	if (OpenFile(buf, &ofs, OF_EXIST) != HFILE_ERROR) {
	    FIXME("NIY: command table to be loaded from '%s'\n", ofs.szPathName);
	}
#endif
    }
    if (!(hRsrc = FindResourceW(hInst, resNameW, (LPWSTR)RT_RCDATA))) {
	WARN("No command table found in resource\n");
    } else if ((hMem = LoadResource(hInst, hRsrc))) {
	ret = MCI_SetCommandTable(LockResource(hMem), type);
    } else {
	WARN("Couldn't load resource.\n");
    }
    TRACE("=> %04x\n", ret);
    return ret;
}

/**************************************************************************
 *                    	mciFreeCommandResource			[WINMM.@]
 */
BOOL WINAPI mciFreeCommandResource(UINT uTable)
{
    TRACE("(%08x)!\n", uTable);

    return MCI_DeleteCommandTable(uTable, FALSE);
}

/**************************************************************************
 * 			MCI_SendCommandFrom32			[internal]
 */
DWORD MCI_SendCommandFrom32(MCIDEVICEID wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
    DWORD		dwRet = MCIERR_INVALID_DEVICE_ID;
    LPWINE_MCIDRIVER	wmd = MCI_GetDriver(wDevID);

    if (wmd) {
	if (wmd->bIs32) {
	    dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
	} else if (pFnMciMapMsg32WTo16) {
	    WINMM_MapType	res;

	    switch (res = pFnMciMapMsg32WTo16(wmd->wType, wMsg, dwParam1, &dwParam2)) {
	    case WINMM_MAP_MSGERROR:
		TRACE("Not handled yet (%s)\n", MCI_MessageToString(wMsg));
		dwRet = MCIERR_DRIVER_INTERNAL;
		break;
	    case WINMM_MAP_NOMEM:
		TRACE("Problem mapping msg=%s from 32a to 16\n", MCI_MessageToString(wMsg));
		dwRet = MCIERR_OUT_OF_MEMORY;
		break;
	    case WINMM_MAP_OK:
	    case WINMM_MAP_OKMEM:
		dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
		if (res == WINMM_MAP_OKMEM)
		    pFnMciUnMapMsg32WTo16(wmd->wType, wMsg, dwParam1, dwParam2);
		break;
	    }
	}
    }
    return dwRet;
}

/**************************************************************************
 * 			MCI_SendCommandFrom16			[internal]
 */
DWORD MCI_SendCommandFrom16(MCIDEVICEID wDevID, UINT16 wMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
    DWORD		dwRet = MCIERR_INVALID_DEVICE_ID;
    LPWINE_MCIDRIVER	wmd = MCI_GetDriver(wDevID);

    if (wmd) {
	dwRet = MCIERR_INVALID_DEVICE_ID;

	if (wmd->bIs32 && pFnMciMapMsg16To32W) {
	    WINMM_MapType		res;

	    switch (res = pFnMciMapMsg16To32W(wmd->wType, wMsg, dwParam1, &dwParam2)) {
	    case WINMM_MAP_MSGERROR:
		TRACE("Not handled yet (%s)\n", MCI_MessageToString(wMsg));
		dwRet = MCIERR_DRIVER_INTERNAL;
		break;
	    case WINMM_MAP_NOMEM:
		TRACE("Problem mapping msg=%s from 16 to 32a\n", MCI_MessageToString(wMsg));
		dwRet = MCIERR_OUT_OF_MEMORY;
		break;
	    case WINMM_MAP_OK:
	    case WINMM_MAP_OKMEM:
		dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
		if (res == WINMM_MAP_OKMEM)
		    pFnMciUnMapMsg16To32W(wmd->wType, wMsg, dwParam1, dwParam2);
		break;

⌨️ 快捷键说明

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