Changeset 4748 for trunk/src/winmm/mci.cpp
- Timestamp:
- Dec 3, 2000, 11:19:43 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/winmm/mci.cpp
r2812 r4748 1 /* $Id: mci.cpp,v 1. 5 2000-02-17 14:09:31sandervl Exp $ */1 /* $Id: mci.cpp,v 1.6 2000-12-03 22:18:17 sandervl Exp $ */ 2 2 3 3 /* 4 * MCI stubs4 * MCI functions 5 5 * 6 6 * Copyright 1998 Joel Troster 7 * 7 * Copyright 1998/1999 Eric Pouech 8 * Copyright 2000 Chris Wohlgemuth 8 9 * 9 10 * Project Odin Software License can be found in LICENSE.TXT … … 15 16 * Includes * 16 17 ****************************************************************************/ 18 19 #define INCL_BASE 20 #define INCL_OS2MM 17 21 18 22 #include <os2win.h> … … 21 25 #include <string.h> 22 26 #include <stdio.h> 27 #include "debugtools.h" 23 28 24 29 #include <misc.h> 25 30 #include <unicode.h> 26 31 32 #include "mcimm.h" 33 27 34 #include "winmm.h" 28 35 29 36 #define DBG_LOCALLOG DBG_mci 37 30 38 #include "dbglocal.h" 39 40 41 /**************************************************************************** 42 * Local functions * 43 ****************************************************************************/ 44 45 /* forward declaration */ 46 static DWORD MCI_SendCommand(UINT mciId, 47 UINT16 uMsg, 48 DWORD dwParam1, 49 DWORD dwParam2); 50 51 static LPWINE_MCIDRIVER MCI_GetDriver(UINT16 wDevID) ; 52 static UINT MCI_GetDriverFromString(LPCSTR lpstrName); 53 54 /****************************************************************************/ 31 55 32 56 ODINDEBUGCHANNEL(WINMM-MCI) … … 38 62 UINT, uStatus) 39 63 { 40 dprintf(("WINMM:mciDriverNotify - stub\n")); 41 return FALSE; 64 TRACE("Entering mciDriverNotify (%08X, %04x, %04X)\n", hwndCallback, uDeviceID, uStatus); 65 66 if (!IsWindow(hwndCallback)) { 67 WARN("bad hwnd for call back (0x%04x)\n", hwndCallback); 68 return FALSE; 69 } 70 TRACE("before PostMessage\n"); 71 PostMessageA(hwndCallback, MM_MCINOTIFY, uStatus, uDeviceID); 72 return TRUE; 42 73 } 43 74 … … 73 104 LPCSTR, pszDevice) 74 105 { 75 dprintf(("WINMM:mciGetDeviceIDA - stub\n"));76 return 0;106 WARN(("WINMM:mciGetDeviceIDA - untested\n")); 107 return MCI_GetDriverFromString(pszDevice); 77 108 } 78 109 … … 100 131 } 101 132 133 /***************************************************************************** 134 * Queries driver data 135 * Parameters: UINT uDeviceID 136 * Variables : 137 * @return : Pointer to driver data (as a DWORD) 138 * Remark : 139 * @status : Completely 140 * 141 * @author : Chris Wohlgemuth [Sun, 2000/11/19] 142 *****************************************************************************/ 102 143 ODINFUNCTION1(DWORD, mciGetDriverData, 103 144 UINT, uDeviceID) 104 145 { 105 dprintf(("WINMM:mciGetDriverData - stub\n")); 106 return 0; 107 } 108 146 LPWINE_MCIDRIVER wmd; 147 148 wmd = MCI_GetDriver(uDeviceID); 149 150 if (!wmd) { 151 dprintf(("WARNING: Bad uDeviceID (mciGetDriverData (mci.cpp line %d)\n",__LINE__)); 152 return 0L; /* Error */ 153 } 154 155 return wmd->dwPrivate; 156 } 157 158 /***************************************************************************** 159 * Converts an error to an error string 160 * Parameters: MCIERROR mcierr, 161 * LPSTR pszText, 162 * UINT cchText 163 * Variables : 164 * @return : API returncode (TRUE/FALSE) 165 * Remark : 166 * @status : Completely 167 * 168 * @author : Wine 169 *****************************************************************************/ 109 170 ODINFUNCTION3(BOOL, mciGetErrorStringA, 110 171 MCIERROR, mcierr, … … 125 186 } 126 187 188 /***************************************************************************** 189 * Converts an error to an error string 190 * Parameters: MCIERROR mcierr, 191 * LPSTR pszText, 192 * UINT cchText 193 * Variables : 194 * @return : API returncode (TRUE/FALSE) 195 * Remark : 196 * @status : Completely 197 * 198 * @author : Wine 199 *****************************************************************************/ 127 200 ODINFUNCTION3(BOOL, mciGetErrorStringW, 128 201 MCIERROR, mcierr, … … 143 216 } 144 217 218 /***************************************************************************** 219 * Converts an error to an error string 220 * Parameters: MCIERROR mcierr, 221 * LPSTR pszText, 222 * UINT cchText 223 * Variables : 224 * @return : API returncode 225 * Remark : 226 * @status : Completely 227 * 228 * @author : Wine 229 *****************************************************************************/ 145 230 ODINFUNCTION2(YIELDPROC, mciGetYieldProc, 146 231 MCIDEVICEID, mciId, 147 232 LPDWORD, pdwYieldData) 148 233 { 149 dprintf(("WINMM:mciGetYieldProc - stub\n")); 150 return 0; 234 LPWINE_MCIDRIVER wmd; 235 236 TRACE("Entering mciGetYieldProc (%u, %p) - untested\n", mciId, pdwYieldData); 237 238 if (!(wmd = MCI_GetDriver(mciId))) { 239 WARN("Bad uDeviceID\n"); 240 return NULL; 241 } 242 if (!wmd->lpfnYieldProc) { 243 WARN("No proc set\n"); 244 return NULL; 245 } 246 if (!wmd->bIs32) { 247 WARN("Proc is 32 bit\n"); 248 return NULL; 249 } 250 return wmd->lpfnYieldProc; 151 251 } 152 252 … … 159 259 return 0; 160 260 } 261 161 262 162 263 ODINFUNCTION4(MCIERROR, mciSendCommandA, … … 166 267 DWORD, dwParam2) 167 268 { 168 dprintf(("WINMM:mciSendCommandA - stub %X %X %X %X\n", mciId, uMsg, dwParam1, dwParam2)); 169 return(MMSYSERR_NODRIVER); 170 } 269 DWORD dwRet; 270 // dprintf(("WINMM:mciSendCommandA - entering %X %X %X %X\n", mciId, uMsg, dwParam1, dwParam2)); 271 dwRet= MCI_SendCommand((UINT) mciId, uMsg, dwParam1, dwParam2) & 0xFFFF; 272 return(dwRet); 273 } 274 171 275 172 276 ODINFUNCTION4(MCIERROR, mciSendCommandW, … … 187 291 { 188 292 dprintf(("WINMM:mciSendStringA - stub\n")); 293 if(lpstrCommand) 294 dprintf(("WINMM:mciSendStringA command: %s\n",lpstrCommand)); 189 295 return(MMSYSERR_NODRIVER); 190 296 } … … 204 310 DWORD, dwData) 205 311 { 206 dprintf(("WINMM:mciSetDriverData - stub\n")); 207 return FALSE; 208 } 312 LPWINE_MCIDRIVER wmd; 313 314 wmd = MCI_GetDriver(uDeviceID); 315 316 if (!wmd) { 317 dprintf(("WARNING: Bad uDeviceID (mciSetDriverData line %d)\n",__LINE__)); 318 return FALSE; 319 } 320 321 wmd->dwPrivate = dwData; 322 return TRUE; 323 } 324 209 325 210 326 ODINFUNCTION3(BOOL, mciSetYieldProc, … … 213 329 DWORD, dwYieldData) 214 330 { 215 dprintf(("WINMM:mciSetYieldProc - stub\n")); 216 return FALSE; 217 } 218 219 331 LPWINE_MCIDRIVER wmd; 332 333 TRACE("WINMM:mciSetYieldProc (%u, %p, %08lx) - untested\n", mciId, fpYieldProc, dwYieldData); 334 335 if (!(wmd = MCI_GetDriver(mciId))) { 336 WARN("Bad uDeviceID\n"); 337 return FALSE; 338 } 339 340 wmd->lpfnYieldProc = fpYieldProc; 341 wmd->dwYieldData = dwYieldData; 342 wmd->bIs32 = TRUE; 343 344 return TRUE; 345 } 346 347 348 /**************************************************************************/ 349 /* heap.c */ 350 /**************************************************************************/ 351 352 #ifdef __GNUC__ 353 #define GET_EIP() (__builtin_return_address(0)) 354 #define SET_EIP(ptr) ((ARENA_INUSE*)(ptr) - 1)->callerEIP = GET_EIP() 355 #else 356 #define GET_EIP() 0 357 #define SET_EIP(ptr) /* nothing */ 358 #endif /* __GNUC__ */ 359 360 /*********************************************************************** 361 * HEAP_strdupA 362 */ 363 static LPSTR HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str ) 364 { 365 LPSTR p = (LPSTR) HeapAlloc( heap, flags, strlen(str) + 1 ); 366 if(p) { 367 //SET_EIP(p); 368 strcpy( p, str ); 369 } 370 return p; 371 } 372 373 374 /**************************************************************************/ 375 /* mmmsystem.c */ 376 /**************************************************************************/ 377 378 static LPWINE_MM_IDATA lpFirstIData = NULL; 379 380 static LPWINE_MM_IDATA MULTIMEDIA_GetIDataNoCheck(void) 381 { 382 DWORD pid = GetCurrentProcessId(); 383 LPWINE_MM_IDATA iData; 384 385 for (iData = lpFirstIData; iData; iData = iData->lpNextIData) { 386 if (iData->dwThisProcess == pid) 387 break; 388 } 389 return iData; 390 } 391 392 /************************************************************************** 393 * MULTIMEDIA_GetIData [internal] 394 */ 395 LPWINE_MM_IDATA MULTIMEDIA_GetIData(void) 396 { 397 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIDataNoCheck(); 398 399 if (!iData) { 400 dprintf(("MULTIMEDIA_GetIData: IData not found for pid=%08lx. Suicide !!!\n", GetCurrentProcessId())); 401 ExitProcess(0); 402 } 403 return iData; 404 } 405 406 407 /************************************************************************** 408 * MULTIMEDIA_CreateIData [internal] 409 */ 410 BOOL MULTIMEDIA_CreateIData(HINSTANCE hInstDLL) 411 { 412 LPWINE_MM_IDATA iData; 413 414 iData = (LPWINE_MM_IDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MM_IDATA)); 415 416 if (!iData) 417 return FALSE; 418 iData->hWinMM32Instance = hInstDLL; 419 iData->dwThisProcess = GetCurrentProcessId(); 420 iData->lpNextIData = lpFirstIData; 421 lpFirstIData = iData; 422 InitializeCriticalSection(&iData->cs); 423 dprintf(("Created IData (%p) for pid %08lx\n", iData, iData->dwThisProcess)); 424 return TRUE; 425 } 426 427 428 /************************************************************************** 429 * MULTIMEDIA_DeleteIData [internal] 430 */ 431 void MULTIMEDIA_DeleteIData(void) 432 { 433 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIDataNoCheck(); 434 LPWINE_MM_IDATA* ppid; 435 436 if (iData) { 437 for (ppid = &lpFirstIData; *ppid; ppid = &(*ppid)->lpNextIData) { 438 if (*ppid == iData) { 439 *ppid = iData->lpNextIData; 440 break; 441 } 442 } 443 /* FIXME: should also free content and resources allocated 444 * inside iData */ 445 HeapFree(GetProcessHeap(), 0, iData); 446 } 447 } 448 449 450 /**************************************************************************/ 451 /* mmmsystem.c */ 452 /**************************************************************************/ 453 454 455 static int MCI_InstalledCount; 456 static LPSTR MCI_lpInstallNames = NULL; 457 458 459 /* First MCI valid device ID (0 means error) */ 460 #define MCI_MAGIC 0x0001 461 462 463 /************************************************************************** 464 * MCI_GetDriver [internal] 465 */ 466 static LPWINE_MCIDRIVER MCI_GetDriver(UINT16 wDevID) 467 { 468 LPWINE_MCIDRIVER wmd = 0; 469 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData(); 470 471 EnterCriticalSection(&iData->cs); 472 for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) { 473 if (wmd->wDeviceID == wDevID) 474 break; 475 } 476 LeaveCriticalSection(&iData->cs); 477 return wmd; 478 } 479 480 /************************************************************************** 481 * MCI_GetDriverFromString [internal] 482 */ 483 static UINT MCI_GetDriverFromString(LPCSTR lpstrName) 484 { 485 LPWINE_MCIDRIVER wmd; 486 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData(); 487 UINT ret = 0; 488 489 if (!lpstrName) 490 return 0; 491 492 if (!lstrcmpiA(lpstrName, "ALL")) 493 return MCI_ALL_DEVICE_ID; 494 495 EnterCriticalSection(&iData->cs); 496 for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) { 497 if (wmd->lpstrElementName && strcmp(wmd->lpstrElementName, lpstrName) == 0) { 498 ret = wmd->wDeviceID; 499 break; 500 } 501 502 if (wmd->lpstrDeviceType && strcmp(wmd->lpstrDeviceType, lpstrName) == 0) { 503 ret = wmd->wDeviceID; 504 break; 505 } 506 507 if (wmd->lpstrAlias && strcmp(wmd->lpstrAlias, lpstrName) == 0) { 508 ret = wmd->wDeviceID; 509 break; 510 } 511 } 512 LeaveCriticalSection(&iData->cs); 513 514 return ret; 515 } 516 517 518 /************************************************************************** 519 * MCI_GetDevTypeFromFileName [internal] 520 */ 521 static DWORD MCI_GetDevTypeFromFileName(LPCSTR fileName, LPSTR buf, UINT len) 522 { 523 LPSTR tmp; 524 525 if ((tmp = strrchr(fileName, '.'))) { 526 GetProfileStringA("mci extensions", tmp + 1, "*", buf, len); 527 if (strcmp(buf, "*") != 0) { 528 return 0; 529 } 530 dprintf(("No [mci extensions] entry for '%s' found. MCI_GetDevTypeFromFileName: line %d, file 'mci.cpp'\n", tmp, __LINE__)); 531 } 532 return MCIERR_EXTENSION_NOT_FOUND; 533 } 534 535 536 #define MAX_MCICMDTABLE 20 537 #define MCI_COMMAND_TABLE_NOT_LOADED 0xFFFE 538 539 540 541 /************************************************************************** 542 * MCI_DefYieldProc [internal] 543 */ 544 //UINT WINAPI MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data) 545 546 UINT16 WINAPI MCI_DefYieldProc(UINT16 wDevID, DWORD data) 547 { 548 INT16 ret; 549 550 #if 0 551 dprintf(("(0x%04x, 0x%08lx)\n", wDevID, data)); 552 #endif 553 if ((HIWORD(data) != 0 && GetActiveWindow() != HIWORD(data)) || 554 (GetAsyncKeyState(LOWORD(data)) & 1) == 0) { 555 /* WINE stuff removed: UserYield16();*/ 556 ret = 0; 557 } else { 558 MSG msg; 559 560 msg.hwnd = HIWORD(data); 561 while (!PeekMessageA(&msg, HIWORD(data), WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)); 562 ret = -1; 563 } 564 return ret; 565 } 566 567 568 /************************************************************************** 569 * MCI_UnLoadMciDriver [internal] 570 */ 571 static BOOL MCI_UnLoadMciDriver(LPWINE_MM_IDATA iData, LPWINE_MCIDRIVER wmd) 572 { 573 LPWINE_MCIDRIVER* tmp; 574 575 #if 0 576 dprintf(("Entering MCI_UnLoadMciDriver...\n")); 577 #endif 578 if (!wmd) 579 return TRUE; 580 581 if (wmd->hDrv) 582 CloseDriver(wmd->hDrv, 0, 0); 583 584 if (wmd->dwPrivate != 0) 585 dprintf(("Unloading mci driver with non nul dwPrivate field\n")); 586 587 EnterCriticalSection(&iData->cs); 588 for (tmp = &iData->lpMciDrvs; *tmp; tmp = &(*tmp)->lpNext) { 589 if (*tmp == wmd) { 590 *tmp = wmd->lpNext; 591 break; 592 } 593 } 594 LeaveCriticalSection(&iData->cs); 595 596 HeapFree(GetProcessHeap(), 0, wmd->lpstrDeviceType); 597 HeapFree(GetProcessHeap(), 0, wmd->lpstrAlias); 598 HeapFree(GetProcessHeap(), 0, wmd->lpstrElementName); 599 600 HeapFree(GetProcessHeap(), 0, wmd); 601 //dprintf(("Leaving MCI_UnLoadMciDriver...\n")); 602 return TRUE; 603 } 604 605 /************************************************************************** 606 * MCI_LoadMciDriver [internal] 607 */ 608 static DWORD MCI_LoadMciDriver(LPWINE_MM_IDATA iData, LPCSTR _strDevTyp, 609 LPWINE_MCIDRIVER* lpwmd) 610 { 611 LPSTR strDevTyp = CharUpperA(HEAP_strdupA(GetProcessHeap(), 0, _strDevTyp)); 612 LPWINE_MCIDRIVER wmd = (LPWINE_MCIDRIVER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wmd)); 613 MCI_OPEN_DRIVER_PARMSA modp; 614 DWORD dwRet = 0; 615 HDRVR hDrv = 0; 616 617 618 dprintf(("Entering MCI_LoadMciDriver...\n")); 619 620 if (!wmd || !strDevTyp) { 621 dwRet = MCIERR_OUT_OF_MEMORY; 622 goto errCleanUp; 623 } 624 625 wmd->lpstrDeviceType = strDevTyp; 626 wmd->lpfnYieldProc = MCI_DefYieldProc; 627 wmd->dwYieldData = VK_CANCEL; 628 wmd->hCreatorTask = NULL; 629 630 631 EnterCriticalSection(&iData->cs); 632 /* wmd must be inserted in list before sending opening the driver, coz' it 633 * may want to lookup at wDevID 634 */ 635 wmd->lpNext = iData->lpMciDrvs; 636 iData->lpMciDrvs = wmd; 637 638 for (modp.wDeviceID = MCI_MAGIC; 639 MCI_GetDriver(modp.wDeviceID) != 0; 640 modp.wDeviceID++); 641 642 wmd->wDeviceID = modp.wDeviceID; 643 644 LeaveCriticalSection(&iData->cs); 645 646 dprintf(("wDevID=%04X strDevTyp: %s\n", modp.wDeviceID, strDevTyp)); 647 648 modp.lpstrParams = NULL; 649 650 hDrv = OpenDriverA(strDevTyp, "mci", (LPARAM)&modp); 651 652 if (!hDrv) { 653 dprintf(("Couldn't load driver for type %s.\n" 654 "If you don't have a windows installation accessible from Wine,\n" 655 "you perhaps forgot to create a [mci] section in system.ini\n", 656 strDevTyp)); 657 dwRet = MCIERR_DEVICE_NOT_INSTALLED; 658 goto errCleanUp; 659 } 660 661 /* FIXME: should also check that module's description is of the form 662 * MODULENAME:[MCI] comment 663 */ 664 665 wmd->hDrv = hDrv; 666 /* some drivers will return 0x0000FFFF, some others 0xFFFFFFFF */ 667 wmd->uSpecificCmdTable = LOWORD(modp.wCustomCommandTable); 668 wmd->uTypeCmdTable = MCI_COMMAND_TABLE_NOT_LOADED; 669 670 dprintf(("Loaded driver %x (%s), type is %d, cmdTable=%08x\n", 671 hDrv, strDevTyp, modp.wType, modp.wCustomCommandTable)); 672 673 674 wmd->wType = modp.wType; 675 676 #if 0 677 dprintf(("mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n", 678 modp.wDeviceID, modp.wType, modp.wDeviceID)); 679 #endif 680 681 *lpwmd = wmd; 682 #if 0 683 dprintf(("Leaving MCI_LoadMciDriver succesful...\n")); 684 #endif 685 return 0; 686 errCleanUp: 687 MCI_UnLoadMciDriver(iData, wmd); 688 // HeapFree(GetProcessHeap(), 0, strDevTyp);<-- done in MCI_UnloadMciDriver 689 *lpwmd = 0; 690 dprintf(("Leaving MCI_LoadMciDriver on error...\n")); 691 return dwRet; 692 } 693 694 695 /************************************************************************** 696 * MCI_SendCommandFrom32 [internal] 697 */ 698 static DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2) 699 { 700 DWORD dwRet = MCIERR_DEVICE_NOT_INSTALLED; 701 LPWINE_MCIDRIVER wmd = MCI_GetDriver(wDevID); 702 703 if (!wmd) { 704 dwRet = MCIERR_INVALID_DEVICE_ID; 705 } else { 706 switch (GetDriverFlags(wmd->hDrv) & (WINE_GDF_EXIST)) { 707 case WINE_GDF_EXIST: 708 dwRet = SendDriverMessage(wmd->hDrv, wMsg, dwParam1, dwParam2); 709 break; 710 default: 711 dprintf(("Unknown driver %u\n", wmd->hDrv)); 712 dwRet = MCIERR_DRIVER_INTERNAL; 713 } 714 } 715 return dwRet; 716 } 717 718 /************************************************************************** 719 * MCI_FinishOpen [internal] 720 */ 721 static DWORD MCI_FinishOpen(LPWINE_MCIDRIVER wmd, LPMCI_OPEN_PARMSA lpParms, 722 DWORD dwParam) 723 { 724 if (dwParam & MCI_OPEN_ELEMENT) 725 wmd->lpstrElementName = HEAP_strdupA(GetProcessHeap(), 0, 726 lpParms->lpstrElementName); 727 728 if (dwParam & MCI_OPEN_ALIAS) 729 wmd->lpstrAlias = HEAP_strdupA(GetProcessHeap(), 0, lpParms->lpstrAlias); 730 731 lpParms->wDeviceID = wmd->wDeviceID; 732 733 return MCI_SendCommandFrom32(wmd->wDeviceID, MCI_OPEN_DRIVER, dwParam, 734 (DWORD)lpParms); 735 } 736 737 /************************************************************************** 738 * MCI_Open [internal] 739 */ 740 static DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSA lpParms) 741 { 742 char strDevTyp[128]; 743 DWORD dwRet; 744 LPWINE_MCIDRIVER wmd = NULL; 745 746 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData(); 747 748 dprintf(("Entering MCI_OPEN...\n")); 749 750 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; 751 752 /* only two low bytes are generic, the other ones are dev type specific */ 753 #define WINE_MCIDRIVER_SUPP (0xFFFF0000|MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT| \ 754 MCI_OPEN_ALIAS|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID| \ 755 MCI_NOTIFY|MCI_WAIT) 756 if ((dwParam & ~WINE_MCIDRIVER_SUPP) != 0) { 757 dprintf(("Unsupported yet dwFlags=%08lX\n", dwParam & ~WINE_MCIDRIVER_SUPP)); 758 } 759 #undef WINE_MCIDRIVER_SUPP 760 761 strDevTyp[0] = 0; 762 763 if (dwParam & MCI_OPEN_TYPE) { 764 if (dwParam & MCI_OPEN_TYPE_ID) { 765 WORD uDevType = LOWORD((DWORD)lpParms->lpstrDeviceType); 766 if (uDevType < MCI_DEVTYPE_FIRST || 767 uDevType > MCI_DEVTYPE_LAST || 768 !LoadStringA(iData->hWinMM32Instance, uDevType, strDevTyp, sizeof(strDevTyp))) /* This gets a name for the device e.g 'cdaudio' */ 769 { 770 dwRet = MCIERR_BAD_INTEGER; 771 goto errCleanUp; 772 } 773 } else { 774 LPSTR ptr; 775 if (lpParms->lpstrDeviceType == NULL) { 776 dwRet = MCIERR_NULL_PARAMETER_BLOCK; 777 goto errCleanUp; 778 } 779 strcpy(strDevTyp, lpParms->lpstrDeviceType); 780 ptr = strchr(strDevTyp, '!'); 781 if (ptr) { 782 /* this behavior is not documented in windows. However, since, in 783 * some occasions, MCI_OPEN handling is translated by WinMM into 784 * a call to mciSendString("open <type>"); this code shall be correct 785 */ 786 if (dwParam & MCI_OPEN_ELEMENT) { 787 dprintf(("Both MCI_OPEN_ELEMENT(%s) and %s are used\n", 788 lpParms->lpstrElementName, strDevTyp)); 789 dwRet = MCIERR_UNRECOGNIZED_KEYWORD; 790 goto errCleanUp; 791 } 792 dwParam |= MCI_OPEN_ELEMENT; 793 *ptr++ = 0; 794 /* FIXME: not a good idea to write in user supplied buffer */ 795 lpParms->lpstrElementName = ptr; 796 } 797 798 } 799 dprintf(("MCI_OPEN (MCI_OPEN_TYPE): devType='%s' !\n", strDevTyp)); 800 } 801 802 if (dwParam & MCI_OPEN_ELEMENT) { 803 dprintf(("lpstrElementName='%s'\n", lpParms->lpstrElementName)); 804 805 if (dwParam & MCI_OPEN_ELEMENT_ID) { 806 dprintf(("Unsupported yet flag MCI_OPEN_ELEMENT_ID\n")); 807 dwRet = MCIERR_UNRECOGNIZED_KEYWORD; 808 goto errCleanUp; 809 } 810 811 if (!lpParms->lpstrElementName) { 812 dwRet = MCIERR_NULL_PARAMETER_BLOCK; 813 goto errCleanUp; 814 } 815 816 #if 0 817 /* Only working on my machine!! CW */ 818 if(lpParms->lpstrElementName[0]=='N') { 819 dprintf(("Discarding drive N:\n")); 820 dwRet = MCIERR_UNRECOGNIZED_KEYWORD; 821 goto errCleanUp; 822 } 823 #endif 824 825 /* type, if given as a parameter, supersedes file extension */ 826 if (!strDevTyp[0] && 827 MCI_GetDevTypeFromFileName(lpParms->lpstrElementName, 828 strDevTyp, sizeof(strDevTyp))) { 829 if (GetDriveTypeA(lpParms->lpstrElementName) != DRIVE_CDROM) { 830 dwRet = MCIERR_EXTENSION_NOT_FOUND; 831 goto errCleanUp; 832 } 833 /* FIXME: this will not work if several CDROM drives are installed on the machine */ 834 strcpy(strDevTyp, "CDAUDIO"); 835 } 836 } 837 838 if (strDevTyp[0] == 0) { 839 dprintf(("Couldn't load driver (MCI_Open line %d)\n",__LINE__)); 840 dwRet = MCIERR_INVALID_DEVICE_NAME; 841 goto errCleanUp; 842 } 843 844 if (dwParam & MCI_OPEN_ALIAS) { 845 dprintf(("MCI_OPEN_ALIAS requested\n")); 846 if (!lpParms->lpstrAlias) { 847 dwRet = MCIERR_NULL_PARAMETER_BLOCK; 848 goto errCleanUp; 849 } 850 dprintf(("Alias='%s' !\n", lpParms->lpstrAlias)); 851 } 852 853 if ((dwRet = MCI_LoadMciDriver(iData, strDevTyp, &wmd))) { 854 goto errCleanUp; 855 } 856 857 858 if ((dwRet = MCI_FinishOpen(wmd, lpParms, dwParam))) { 859 dprintf(("Failed to open driver (MCI_OPEN_DRIVER) [%08lx], closing\n", dwRet)); 860 /* FIXME: is dwRet the correct ret code ? */ 861 goto errCleanUp; 862 } 863 864 865 /* only handled devices fall through */ 866 dprintf(("wDevID=%04X wDeviceID=%d dwRet=%ld\n", wmd->wDeviceID, lpParms->wDeviceID, dwRet)); 867 868 if (dwParam & MCI_NOTIFY) 869 // mciDriverNotify16(lpParms->dwCallback, wmd->wDeviceID, MCI_NOTIFY_SUCCESSFUL); 870 dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Open (line %d)\n",__LINE__)); 871 872 return 0; 873 874 errCleanUp: 875 876 if (wmd) MCI_UnLoadMciDriver(iData, wmd); 877 878 if (dwParam & MCI_NOTIFY) 879 // mciDriverNotify16(lpParms->dwCallback, 0, MCI_NOTIFY_FAILURE); 880 dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Open (line %d)\n",__LINE__)); 881 882 dprintf(("Leaving MCI_Open on error...\n")); 883 return dwRet; 884 } 885 886 887 /************************************************************************** 888 * MCI_Close [internal] 889 */ 890 static DWORD MCI_Close(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms) 891 { 892 DWORD dwRet; 893 LPWINE_MCIDRIVER wmd; 894 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData(); 895 896 //dprintf(("(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms)); 897 898 if (wDevID == MCI_ALL_DEVICE_ID) { 899 LPWINE_MCIDRIVER next; 900 901 EnterCriticalSection(&iData->cs); 902 /* FIXME: shall I notify once after all is done, or for 903 * each of the open drivers ? if the latest, which notif 904 * to return when only one fails ? 905 */ 906 for (wmd = iData->lpMciDrvs; wmd; ) { 907 next = wmd->lpNext; 908 MCI_Close(wmd->wDeviceID, dwParam, lpParms); 909 wmd = next; 910 } 911 LeaveCriticalSection(&iData->cs); 912 return 0; 913 } 914 915 if (!(wmd = MCI_GetDriver(wDevID))) { 916 return MCIERR_INVALID_DEVICE_ID; 917 } 918 919 dwRet = MCI_SendCommandFrom32(wDevID, MCI_CLOSE_DRIVER, dwParam, (DWORD)lpParms); 920 921 MCI_UnLoadMciDriver(iData, wmd); 922 923 if (dwParam & MCI_NOTIFY) 924 dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Close (line %d)\n",__LINE__)); 925 // mciDriverNotify16(lpParms->dwCallback, wDevID, 926 // (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE); 927 928 return dwRet; 929 } 930 931 932 /************************************************************************** 933 * MCI_WriteString [internal] 934 */ 935 DWORD MCI_WriteString(LPSTR lpDstStr, DWORD dstSize, LPCSTR lpSrcStr) 936 { 937 DWORD ret = 0; 938 939 if (lpSrcStr) { 940 if (dstSize <= strlen(lpSrcStr)) { 941 lstrcpynA(lpDstStr, lpSrcStr, dstSize - 1); 942 ret = MCIERR_PARAM_OVERFLOW; 943 } else { 944 strcpy(lpDstStr, lpSrcStr); 945 } 946 } else { 947 *lpDstStr = 0; 948 } 949 return ret; 950 } 951 952 953 /************************************************************************** 954 * MCI_Sysinfo [internal] 955 */ 956 static DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSA lpParms) 957 { 958 DWORD ret = MCIERR_INVALID_DEVICE_ID; 959 LPWINE_MCIDRIVER wmd; 960 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData(); 961 962 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; 963 964 TRACE("(%08x, %08lX, %08lX[num=%ld, wDevTyp=%u])\n", 965 uDevID, dwFlags, (DWORD)lpParms, lpParms->dwNumber, lpParms->wDeviceType); 966 967 switch (dwFlags & ~MCI_SYSINFO_OPEN) { 968 case MCI_SYSINFO_QUANTITY: 969 { 970 DWORD cnt = 0; 971 972 if (lpParms->wDeviceType < MCI_DEVTYPE_FIRST || 973 lpParms->wDeviceType > MCI_DEVTYPE_LAST) { 974 if (dwFlags & MCI_SYSINFO_OPEN) { 975 TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers\n"); 976 EnterCriticalSection(&iData->cs); 977 for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) { 978 cnt++; 979 } 980 LeaveCriticalSection(&iData->cs); 981 } else { 982 TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers\n"); 983 cnt = MCI_InstalledCount; 984 } 985 } else { 986 if (dwFlags & MCI_SYSINFO_OPEN) { 987 TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers of type %u\n", 988 lpParms->wDeviceType); 989 EnterCriticalSection(&iData->cs); 990 for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) { 991 if (wmd->wType == lpParms->wDeviceType) 992 cnt++; 993 } 994 LeaveCriticalSection(&iData->cs); 995 } else { 996 TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers of type %u\n", 997 lpParms->wDeviceType); 998 FIXME("Don't know how to get # of MCI devices of a given type\n"); 999 cnt = 1; 1000 } 1001 } 1002 *(DWORD*)lpParms->lpstrReturn = cnt; 1003 } 1004 TRACE("(%ld) => '%ld'\n", lpParms->dwNumber, *(DWORD*)lpParms->lpstrReturn); 1005 ret = MCI_INTEGER_RETURNED; 1006 break; 1007 case MCI_SYSINFO_INSTALLNAME: 1008 TRACE("MCI_SYSINFO_INSTALLNAME \n"); 1009 if ((wmd = MCI_GetDriver(uDevID))) { 1010 ret = MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize, 1011 wmd->lpstrDeviceType); 1012 } else { 1013 *lpParms->lpstrReturn = 0; 1014 ret = MCIERR_INVALID_DEVICE_ID; 1015 } 1016 TRACE("(%ld) => '%s'\n", lpParms->dwNumber, lpParms->lpstrReturn); 1017 break; 1018 case MCI_SYSINFO_NAME: 1019 TRACE("MCI_SYSINFO_NAME\n"); 1020 if (dwFlags & MCI_SYSINFO_OPEN) { 1021 FIXME("Don't handle MCI_SYSINFO_NAME|MCI_SYSINFO_OPEN (yet)\n"); 1022 ret = MCIERR_UNRECOGNIZED_COMMAND; 1023 } else if (lpParms->dwNumber > MCI_InstalledCount) { 1024 ret = MCIERR_OUTOFRANGE; 1025 } else { 1026 DWORD count = lpParms->dwNumber; 1027 LPSTR ptr = MCI_lpInstallNames; 1028 1029 while (--count > 0) ptr += strlen(ptr) + 1; 1030 ret = MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize, ptr); 1031 } 1032 TRACE("(%ld) => '%s'\n", lpParms->dwNumber, lpParms->lpstrReturn); 1033 break; 1034 default: 1035 TRACE("Unsupported flag value=%08lx\n", dwFlags); 1036 ret = MCIERR_UNRECOGNIZED_COMMAND; 1037 } 1038 return ret; 1039 } 1040 1041 1042 /************************************************************************** 1043 * MCI_Break [internal] 1044 */ 1045 static DWORD MCI_Break(UINT wDevID, DWORD dwFlags, LPMCI_BREAK_PARMS lpParms) 1046 { 1047 DWORD dwRet = 0; 1048 1049 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; 1050 1051 if (dwFlags & MCI_NOTIFY) 1052 dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Break (line %d)\n",__LINE__)); 1053 // mciDriverNotify16(lpParms->dwCallback, wDevID, 1054 // (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE); 1055 1056 return dwRet; 1057 } 1058 1059 1060 /************************************************************************** 1061 * MCI_SendCommand [internal] 1062 */ 1063 static DWORD MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD dwParam1, 1064 DWORD dwParam2) 1065 { 1066 DWORD dwRet = MCIERR_UNRECOGNIZED_COMMAND; 1067 1068 switch (wMsg) { 1069 case MCI_OPEN: 1070 dwRet = MCI_Open(dwParam1, (LPMCI_OPEN_PARMSA)dwParam2); 1071 break; 1072 case MCI_CLOSE: 1073 dwRet = MCI_Close(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2); 1074 break; 1075 case MCI_SYSINFO: 1076 dwRet = MCI_SysInfo(wDevID, dwParam1, (LPMCI_SYSINFO_PARMSA)dwParam2); 1077 break; 1078 case MCI_BREAK: 1079 dwRet = MCI_Break(wDevID, dwParam1, (LPMCI_BREAK_PARMS)dwParam2); 1080 break; 1081 // case MCI_SOUND: 1082 /* FIXME: it seems that MCI_SOUND needs the same handling as MCI_BREAK 1083 * but I couldn't get any doc on this MCI message 1084 */ 1085 // break; 1086 default: 1087 if (wDevID == MCI_ALL_DEVICE_ID) { 1088 dprintf(("MCI_SendCommand: unhandled MCI_ALL_DEVICE_ID\n")); 1089 dwRet = MCIERR_CANNOT_USE_ALL; 1090 } else { 1091 dwRet=MCI_SendCommandFrom32(wDevID, wMsg, dwParam1, dwParam2); 1092 } 1093 break; 1094 } 1095 return dwRet; 1096 } 1097 1098 1099 1100 1101 /************************************************************************** 1102 * MULTIMEDIA_MciInit [internal] 1103 * 1104 * Initializes the MCI internal variables. 1105 * 1106 */ 1107 BOOL MULTIMEDIA_MciInit(void) 1108 { 1109 LPSTR ptr1, ptr2; 1110 HKEY hWineConf; 1111 HKEY hkey; 1112 DWORD err; 1113 DWORD type; 1114 DWORD count = 2048; 1115 1116 MCI_InstalledCount = 0; 1117 ptr1 = MCI_lpInstallNames = (char*) HeapAlloc(GetProcessHeap(), 0, count); 1118 1119 if (!MCI_lpInstallNames) 1120 return FALSE; 1121 1122 #if 0 1123 /* FIXME: should do also some registry diving here ? */ 1124 if (!(err = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config", &hWineConf)) && 1125 !(err = RegOpenKeyA(hWineConf, "options", &hkey))) { 1126 err = RegQueryValueExA(hkey, "mci", 0, &type, MCI_lpInstallNames, &count); 1127 RegCloseKey(hkey); 1128 FIXME("Registry handling for mci drivers not changed for odin yet. Verbatim copy from WINE (line %d)",__LINE__); 1129 } 1130 #endif 1131 FIXME("No Registry querying for mci drivers yet! (line %d)",__LINE__); 1132 err=1; 1133 if (!err) { 1134 TRACE("Wine => '%s' \n", ptr1); 1135 while ((ptr2 = strchr(ptr1, ':')) != 0) { 1136 *ptr2++ = 0; 1137 TRACE("---> '%s' \n", ptr1); 1138 MCI_InstalledCount++; 1139 ptr1 = ptr2; 1140 } 1141 MCI_InstalledCount++; 1142 TRACE("---> '%s' \n", ptr1); 1143 ptr1 += strlen(ptr1) + 1; 1144 } else { 1145 GetPrivateProfileStringA("mci", NULL, "", MCI_lpInstallNames, count, "SYSTEM.INI"); 1146 while (strlen(ptr1) > 0) { 1147 TRACE("---> '%s' \n", ptr1); 1148 ptr1 += strlen(ptr1) + 1; 1149 MCI_InstalledCount++; 1150 } 1151 } 1152 //RegCloseKey(hWineConf); 1153 return TRUE; 1154 }
Note:
See TracChangeset
for help on using the changeset viewer.