Changeset 1998 for trunk/src


Ignore:
Timestamp:
Dec 6, 1999, 9:40:55 PM (26 years ago)
Author:
sandervl
Message:

PD: Ported MMIO from Wine (v991031)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/winmm/mmio.cpp

    r588 r1998  
    1 /* $Id: mmio.cpp,v 1.4 1999-08-19 18:46:05 phaller Exp $ */
    2 
    31/*
    4  * MMIO stubs
     2 * MMIO functions
    53 *
    6  * Copyright 1998 Joel Troster
     4 * Copyright 1999 Przemyslaw Dobrowolski
    75 *
     6 * Based on Wine code:
     7 * Copyright 1998 Andrew Taylor
     8 * Copyright 1998 Ove Kåven
    89 *
    9  * Project Odin Software License can be found in LICENSE.TXT
    10  *
    11  */
    12 
    13 
    14 /****************************************************************************
    15  * Includes                                                                 *
    16  ****************************************************************************/
     10 */
    1711
    1812#include <os2win.h>
    1913#include <mmsystem.h>
    2014#include <odinwrap.h>
     15#include <misc.h>
    2116#include <string.h>
    22 #include <misc.h>
    23 #include <unicode.h>
    24 
    25 #include "winmm.h"
    26 
     17#include <heapstring.h>
     18
     19#include <stdlib.h>
     20#include <errno.h>
     21#include "windef.h"
     22#include "file.h"
     23#include "mmsystem.h"
     24#include "debugtools.h"
    2725
    2826ODINDEBUGCHANNEL(WINMM-MMIO)
    2927
    30 
    31 ODINFUNCTION3(MMRESULT, mmioAdvance,
    32               HMMIO, hmmio,
    33               LPMMIOINFO, lpmmioinfo,
    34               UINT, fuOperation)
    35 {
    36   dprintf(("WINMM:mmioAdvance - stub\n"));
    37   return(MMSYSERR_NODRIVER);
    38 }
    39 
    40 ODINFUNCTION3(MMRESULT, mmioAscend,
    41               HMMIO, hmmio,
    42               LPMMCKINFO, lpmmcki,
    43               UINT, uReserved)
    44 {
    45   dprintf(("WINMM:mmioAscend - stub\n"));
    46   return(MMSYSERR_NODRIVER);
    47 }
    48 
     28/**************************************************************************
     29 *               mmioDosIOProc           [internal]
     30 */
     31static LRESULT WIN32API mmioDosIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage, LPARAM lParam1, LPARAM lParam2)
     32{
     33        dprintf(("mmioDosIOProc (%p, %X, %ld, %ld);\n", lpmmioinfo, uMessage, lParam1, lParam2));
     34
     35        switch (uMessage) {
     36
     37                case MMIOM_OPEN: {
     38                        /* Parameters:
     39                         * lParam1 = szFileName parameter from mmioOpen
     40             * lParam2 = resrved
     41                         * NOTE: lDiskOffset automatically set to zero
     42                         */
     43
     44                        OFSTRUCT ofs;
     45                        LPSTR szFileName = (LPSTR) lParam1;
     46
     47                        if (lpmmioinfo->dwFlags & MMIO_GETTEMP) {
     48                                dprintf(("WINMM: mmioDosIOProc MMIO_GETTEMP not implemented\n"));
     49                                return MMIOERR_CANNOTOPEN;
     50                        }
     51
     52                        lpmmioinfo->adwInfo[0] =
     53                                (DWORD) OpenFile(szFileName, &ofs, lpmmioinfo->dwFlags);
     54                        if (lpmmioinfo->adwInfo[0] == -1)
     55                                return MMIOERR_CANNOTOPEN;
     56
     57                        return 0;
     58                }
     59
     60                case MMIOM_CLOSE: {
     61                        /* Parameters:
     62                         * lParam1 = wFlags parameter from mmioClose
     63                         * lParam2 = unused
     64                         * Returns: zero on success, error code on error
     65                         */
     66
     67                        UINT uFlags = (UINT)lParam1;
     68
     69                        if (uFlags & MMIO_FHOPEN)
     70                                return 0;
     71
     72                        _lclose((HFILE)lpmmioinfo->adwInfo[0]);
     73                        return 0;
     74
     75                }
     76
     77                case MMIOM_READ: {
     78                        /* Parameters:
     79                         * lParam1 = huge pointer to read buffer
     80                         * lParam2 = number of bytes to read
     81                         * Returns: number of bytes read, 0 for EOF, -1 for error (error code
     82                         *         in wErrorRet)
     83                         * NOTE: lDiskOffset should be updated
     84                         */
     85
     86                        HPSTR pch = (HPSTR) lParam1;
     87                        LONG cch = (LONG) lParam2;
     88                        LONG count;
     89
     90                        count = _lread((HFILE)lpmmioinfo->adwInfo[0], pch, cch);
     91                        if (count != -1)
     92                                lpmmioinfo->lDiskOffset += count;
     93
     94                        return count;
     95                }
     96
     97                case MMIOM_WRITE:
     98                case MMIOM_WRITEFLUSH: {
     99                        /* no internal buffering, so WRITEFLUSH handled same as WRITE */
     100
     101                        /* Parameters:
     102                         * lParam1 = huge pointer to write buffer
     103                         * lParam2 = number of bytes to write
     104                         * Returns: number of bytes written, -1 for error (error code in
     105                         *              wErrorRet)
     106                         * NOTE: lDiskOffset should be updated
     107                         */
     108
     109                        HPSTR pch = (HPSTR) lParam1;
     110                        LONG cch = (LONG) lParam2;
     111                        LONG count;
     112
     113                        count = _hwrite((HFILE)lpmmioinfo->adwInfo[0], pch, cch);
     114                        if (count != -1)
     115                                lpmmioinfo->lDiskOffset += count;
     116
     117                        return count;
     118                }
     119
     120                case MMIOM_SEEK: {
     121            /* Parameters:
     122             * lParam1 = new position
     123             * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
     124             * Returns: new file postion, -1 on error
     125             * NOTE: lDiskOffset should be updated
     126             */
     127
     128            LONG Offset = (LONG) lParam1;
     129            LONG Whence = (LONG) lParam2;
     130            LONG pos;
     131
     132            pos = _llseek((HFILE)lpmmioinfo->adwInfo[0], Offset, Whence);
     133            if (pos != -1)
     134                lpmmioinfo->lDiskOffset = pos;
     135
     136            return pos;
     137                }
     138                 
     139                case MMIOM_RENAME: {
     140            /* Parameters:
     141             * lParam1 = old name
     142             * lParam2 = new name
     143             * Returns: zero on success, non-zero on failure
     144             */
     145
     146            dprintf(("WINMM: mmioDosIOProc MMIOM_RENAME unimplemented\n"));
     147            return MMIOERR_FILENOTFOUND;
     148                }
     149
     150                default:
     151                        dprintf(("WINMM: mmioDosIOProc unexpected message %u\n", uMessage));
     152                        return 0;
     153        }
     154       
     155        return 0;
     156}
     157
     158/**************************************************************************
     159*               mmioMemIOProc           [internal]
     160*/
     161static LRESULT WIN32API mmioMemIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage, LPARAM lParam1, LPARAM lParam2) {
     162//      TRACE("(%p,0x%04x,0x%08lx,0x%08lx)\n",lpmmioinfo,uMessage,lParam1,lParam2);
     163        switch (uMessage) {
     164
     165                case MMIOM_OPEN: {
     166                        /* Parameters:
     167                         * lParam1 = filename (must be NULL)
     168                         * lParam2 = reserved
     169                         * Returns: zero on success, error code on error
     170                         * NOTE: lDiskOffset automatically set to zero
     171                         */
     172
     173                        if (!(lpmmioinfo->dwFlags & MMIO_CREATE))
     174                                lpmmioinfo->pchEndRead = lpmmioinfo->pchEndWrite;
     175
     176                        return 0;
     177                }
     178
     179                case MMIOM_CLOSE: {
     180                        /* Parameters:
     181                         * lParam1 = wFlags parameter from mmioClose
     182                         * lParam2 = unused
     183                         * Returns: zero on success, error code on error
     184                         */
     185
     186                        return 0;
     187
     188                }
     189
     190                case MMIOM_READ: {
     191                        /* Parameters:
     192                         * lParam1 = huge pointer to read buffer
     193                         * lParam2 = number of bytes to read
     194                         * Returns: number of bytes read, 0 for EOF, -1 for error (error code
     195                         *         in wErrorRet)
     196                         * NOTE: lDiskOffset should be updated
     197                         */
     198
     199                        /* HPSTR pch = (HPSTR) lParam1; */
     200                        /* LONG cch = (LONG) lParam2; */
     201
     202                        dprintf(("WINMM (mmioMemIOProc) MMIOM_READ on memory files should not occur, buffer may be lost!\n"));
     203                        return 0;
     204                }
     205
     206                case MMIOM_WRITE:
     207                case MMIOM_WRITEFLUSH: {
     208                        /* no internal buffering, so WRITEFLUSH handled same as WRITE */
     209
     210                        /* Parameters:
     211                         * lParam1 = huge pointer to write buffer
     212                         * lParam2 = number of bytes to write
     213                         * Returns: number of bytes written, -1 for error (error code in
     214                         *              wErrorRet)
     215                         * NOTE: lDiskOffset should be updated
     216                         */
     217
     218                        /* HPSTR pch = (HPSTR) lParam1; */
     219                        /* LONG cch = (LONG) lParam2; */
     220
     221                        dprintf(("WINMM (mmioMemIOProc) MMIOM_WRITE on memory files should not occur, buffer may be lost!\n"));
     222                        return 0;
     223                }
     224
     225                case MMIOM_SEEK: {
     226                        /* Parameters:
     227                         * lParam1 = new position
     228                         * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
     229                         * Returns: new file postion, -1 on error
     230                         * NOTE: lDiskOffset should be updated
     231                         */
     232
     233                        /* LONG Offset = (LONG) lParam1; */
     234                        /* LONG Whence = (LONG) lParam2; */
     235
     236                        dprintf(("WINMM (mmioMemIOProc) MMIOM_SEEK on memory files should not occur, buffer may be lost!\n"));
     237                        return -1;
     238                }
     239                 
     240                default:
     241                        dprintf(("WINMM (mmioMemIOProc) unexpected message %u\n", uMessage));
     242                        return 0;
     243        }
     244       
     245        return 0;
     246}
     247
     248/**************************************************************************
     249 *              MMIO_Open               [internal]
     250 */
     251static HMMIO MMIO_Open(LPSTR szFileName, LPMMIOINFO refmminfo, DWORD dwOpenFlags)
     252{
     253        LPMMIOINFO lpmminfo;
     254        HMMIO      hmmio;
     255       
     256//      TRACE("('%s', %08lX);\n", szFileName, dwOpenFlags);
     257       
     258        if (dwOpenFlags & MMIO_PARSE) {
     259                char    buffer[MAX_PATH];
     260               
     261                if (GetFullPathNameA(szFileName, sizeof(buffer), buffer, NULL) >= sizeof(buffer))
     262                        return (HMMIO)FALSE;
     263                strcpy(szFileName, buffer);
     264                return (HMMIO)TRUE;
     265        }
     266
     267        hmmio = GlobalAlloc(GHND, sizeof(MMIOINFO));
     268        lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
     269        if (lpmminfo == NULL)
     270                return 0;
     271        memset(lpmminfo, 0, sizeof(MMIOINFO));
     272
     273        /* assume DOS file if not otherwise specified */
     274        if (refmminfo->fccIOProc == 0 && refmminfo->pIOProc == NULL) {
     275                lpmminfo->fccIOProc = FOURCC_DOS;
     276                lpmminfo->pIOProc = (LPMMIOPROC) mmioDosIOProc;
     277        }
     278        /* if just the four character code is present, look up IO proc */
     279        else if (refmminfo->pIOProc == NULL) {
     280
     281                lpmminfo->fccIOProc = refmminfo->fccIOProc;
     282                lpmminfo->pIOProc = mmioInstallIOProcA(refmminfo->fccIOProc, NULL, MMIO_FINDPROC);
     283
     284        }
     285        /* if IO proc specified, use it and specified four character code */
     286        else {
     287
     288                lpmminfo->fccIOProc = refmminfo->fccIOProc;
     289                lpmminfo->pIOProc = (LPMMIOPROC)refmminfo->pIOProc;
     290        }
     291
     292        if (dwOpenFlags & MMIO_ALLOCBUF) {
     293                if ((refmminfo->wErrorRet = mmioSetBuffer(hmmio, NULL, MMIO_DEFAULTBUFFER, 0))) {
     294                        return 0;
     295                }
     296        } else if (lpmminfo->fccIOProc == FOURCC_MEM) {
     297                if ((refmminfo->wErrorRet = mmioSetBuffer(hmmio, refmminfo->pchBuffer, refmminfo->cchBuffer, 0))) {
     298                        return 0;
     299                }
     300        }
     301       
     302        /* see mmioDosIOProc for that one */
     303        lpmminfo->adwInfo[0] = refmminfo->adwInfo[0];
     304        lpmminfo->dwFlags = dwOpenFlags;
     305        lpmminfo->hmmio = hmmio;
     306       
     307        /* call IO proc to actually open file */
     308        refmminfo->wErrorRet = (UINT) mmioSendMessage(hmmio, MMIOM_OPEN, (LPARAM) szFileName, (LPARAM) 0);
     309       
     310        GlobalUnlock(hmmio);
     311       
     312        if (refmminfo->wErrorRet != 0) {
     313                GlobalFree(hmmio);
     314                return 0;
     315        }
     316       
     317        return hmmio;
     318}
     319
     320/**************************************************************************
     321 *                              mmioOpenW                       [WINMM.123]
     322 */
     323ODINFUNCTION3(HMMIO, mmioOpenW,
     324              LPWSTR,szFileName,
     325              LPMMIOINFO,lpmmioinfo,
     326              DWORD,dwOpenFlags)
     327{
     328        LPSTR   szFn = HEAP_strdupWtoA(GetProcessHeap(),0,szFileName);
     329        HMMIO   ret = mmioOpenA(szFn, lpmmioinfo, dwOpenFlags);
     330
     331        HeapFree(GetProcessHeap(),0,szFn);
     332        return ret;
     333}
     334
     335/**************************************************************************
     336 *                              mmioOpenA                       [WINMM.122]
     337 */
     338ODINFUNCTION3(HMMIO, mmioOpenA,
     339              LPSTR,szFileName,
     340              LPMMIOINFO,lpmmioinfo,
     341              DWORD,dwOpenFlags)
     342{
     343        HMMIO   ret;
     344       
     345        if (lpmmioinfo) {
     346                ret = MMIO_Open(szFileName, lpmmioinfo, dwOpenFlags);
     347        } else {
     348           MMIOINFO     mmioinfo;
     349
     350           mmioinfo.fccIOProc = 0;
     351           mmioinfo.pIOProc = NULL;
     352           mmioinfo.pchBuffer = NULL;
     353           mmioinfo.cchBuffer = 0;
     354
     355           ret = MMIO_Open(szFileName, &mmioinfo, dwOpenFlags);
     356        }
     357        return ret;
     358}
     359
     360   
     361/**************************************************************************
     362 *                              mmioClose               [WINMM.114]
     363 */
    49364ODINFUNCTION2(MMRESULT, mmioClose,
    50               HMMIO, hmmio,
    51               UINT, fuOption)
    52 {
    53   dprintf(("WINMM:mmioClose - stub\n"));
    54   return 0;
    55 }
    56 
    57 /******************************************************************************/
    58 //HMMIO hmmio;  /* identifies file      */
    59 //LPMMCKINFO lpmmcki;   /* address of chunk information structure       */
    60 //UINT fuOptions;       /* chunk creation options       */
    61 /******************************************************************************/
    62 ODINFUNCTION3(MMRESULT, mmioCreateChunk,
    63               HMMIO, hmmio,
    64               LPMMCKINFO, lpmmcki,
    65               UINT, fuOptions)
    66 {
    67     dprintf(("WINMM:mmioCreateChunk - stub\n"));
    68     return 0;
    69 }
    70 
    71 /******************************************************************************/
    72 //HMMIO hmmio;  /* handle of open RIFF file     */
    73 //LPMMCKINFO lpmmcki;   /* address of chunk information structure       */
    74 //LPMMCKINFO lpmmckiParent;     /* address of optional parent structure */
    75 //UINT fuSearch;        /* search-option flags  */
    76 /******************************************************************************/
    77 ODINFUNCTION4(MMRESULT, mmioDescend,
    78               HMMIO, hmmio,
    79               LPMMCKINFO, lpmmcki,
    80               const MMCKINFO *, lpmmckiParent,
    81               UINT, fuSearch)
    82 {
    83     dprintf(("WINMM:mmioDescend - stub\n"));
    84     return 0;
    85 }
    86 
    87 ODINFUNCTION2(MMRESULT, mmioFlush,
    88               HMMIO, hmmio,
    89               UINT, fuFlush)
    90 {
    91   dprintf(("WINMM:mmioFlush - stub\n"));
    92   return 0;
    93 }
    94 
    95 ODINFUNCTION3(MMRESULT, mmioGetInfo,
    96               HMMIO, hmmio,
    97               LPMMIOINFO, lpmmioinfo,
    98               UINT, uReserved)
    99 {
    100   dprintf(("WINMM:mmioGetInfo - stub\n"));
    101   return(MMSYSERR_NODRIVER);
    102 }
    103 
    104 //   mmioInstallIOProc16        = _mmioInstallIOProc16@??     @120
    105 
    106 ODINFUNCTION3(LPMMIOPROC, mmioInstallIOProcA,
    107               FOURCC, fccIOProc,
    108               LPMMIOPROC, pIOProc,
    109               DWORD, dwFlags)
    110 {
    111   dprintf(("WINMM:mmioInstallIOProcA - stub\n"));
    112   return 0;
     365              HMMIO,hmmio,
     366              UINT,uFlags)
     367{
     368        LPMMIOINFO lpmminfo;
     369        MMRESULT   result;
     370
     371//      TRACE("(%04X, %04X);\n", hmmio, uFlags);
     372
     373        lpmminfo = (LPMMIOINFO) GlobalLock(hmmio);
     374        if (lpmminfo == NULL)
     375                return 0;
     376
     377        /* flush the file - if error reported, ignore */
     378        if (mmioFlush(hmmio, MMIO_EMPTYBUF) != 0)
     379                lpmminfo->dwFlags &= ~MMIO_DIRTY;
     380
     381        result = mmioSendMessage(hmmio,MMIOM_CLOSE,(LPARAM)uFlags,(LPARAM)0);
     382
     383        mmioSetBuffer(hmmio, NULL, 0, 0);
     384
     385        GlobalUnlock(hmmio);
     386        GlobalFree(hmmio);
     387
     388        return result;
     389}
     390
     391
     392
     393/**************************************************************************
     394 *                              mmioRead                [WINMM.124]
     395 */
     396ODINFUNCTION3(LONG, mmioRead,
     397              HMMIO,hmmio,
     398              HPSTR,pch,
     399              LONG,cch)
     400{
     401        LONG       count;
     402        LPMMIOINFO lpmminfo;
     403
     404//      TRACE("(%04X, %p, %ld);\n", hmmio, pch, cch);
     405
     406        lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
     407        if (lpmminfo == NULL)
     408                return -1;
     409
     410        if (lpmminfo->pchNext != lpmminfo->pchEndRead) {
     411                count = lpmminfo->pchEndRead - lpmminfo->pchNext;
     412                if (count > cch || count < 0) count = cch;
     413                memcpy(pch, lpmminfo->pchNext, count);
     414                lpmminfo->pchNext += count;
     415                pch += count;
     416                cch -= count;
     417        } else
     418                count = 0;
     419
     420        if (cch&&(lpmminfo->fccIOProc!=FOURCC_MEM)) {
     421                if (lpmminfo->cchBuffer) {
     422                        mmioFlush(hmmio, MMIO_EMPTYBUF);
     423
     424                        while (cch) {
     425                                LONG size;
     426                                lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
     427                                lpmminfo->pchNext = lpmminfo->pchBuffer;
     428                                lpmminfo->pchEndRead = lpmminfo->pchBuffer;
     429                                size = mmioSendMessage(hmmio, MMIOM_READ,
     430                                                (LPARAM) lpmminfo->pchBuffer,
     431                                                (LPARAM) lpmminfo->cchBuffer);
     432                                if (size<=0) break;
     433                                lpmminfo->pchEndRead = lpmminfo->pchBuffer + size;
     434                                if (size > cch) size = cch;
     435                                memcpy(pch, lpmminfo->pchNext, size);
     436                                lpmminfo->pchNext += size;
     437                                pch += size;
     438                                cch -= size;
     439                                count += size;
     440                        }
     441                } else {
     442                        count += mmioSendMessage(hmmio, MMIOM_READ, (LPARAM) pch, (LPARAM) cch);
     443                        if (count>0) lpmminfo->lBufOffset += count;
     444                }
     445        }
     446
     447        GlobalUnlock(hmmio);
     448        TRACE("count=%ld\n", count);
     449        return count;
     450}
     451
     452/**************************************************************************
     453 *                              mmioWrite               [WINMM.133]
     454 */
     455ODINFUNCTION3(LONG, mmioWrite,
     456              HMMIO,hmmio,
     457              HPCSTR,pch,
     458              LONG,cch)
     459{
     460        LONG       count;
     461        LPMMIOINFO lpmminfo;
     462
     463//      TRACE("(%04X, %p, %ld);\n", hmmio, pch, cch);
     464
     465        lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
     466        if (lpmminfo == NULL)
     467                return -1;
     468
     469        if (lpmminfo->cchBuffer) {
     470                count = 0;
     471                while (cch) {
     472                        if (lpmminfo->pchNext != lpmminfo->pchEndWrite) {
     473                                count = lpmminfo->pchEndWrite - lpmminfo->pchNext;
     474                                if (count > cch || count < 0) count = cch;
     475                                memcpy(lpmminfo->pchNext, pch, count);
     476                                lpmminfo->pchNext += count;
     477                                pch += count;
     478                                cch -= count;
     479                                lpmminfo->dwFlags |= MMIO_DIRTY;
     480                        } else
     481                        if (lpmminfo->fccIOProc==FOURCC_MEM) {
     482                                if (lpmminfo->adwInfo[0]) {
     483                                        /* from where would we get the memory handle? */
     484                                        dprintf(("WINMM (mmioWrite) memory file expansion not implemented!\n"));
     485                                } else break;
     486                        }
     487
     488                        if (lpmminfo->pchNext == lpmminfo->pchEndWrite
     489                                && mmioFlush(hmmio, MMIO_EMPTYBUF)) break;
     490                }
     491        } else {
     492                count = mmioSendMessage(hmmio, MMIOM_WRITE, (LPARAM) pch, (LPARAM) cch);
     493                lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
     494        }
     495
     496        GlobalUnlock(hmmio);
     497//      TRACE("count=%ld\n", count);
     498        return count;
     499}
     500
     501/**************************************************************************
     502 *                              mmioSeek                [MMSYSTEM.1214]
     503 */
     504ODINFUNCTION3(LONG, mmioSeek,
     505              HMMIO, hmmio,
     506              LONG,lOffset,
     507              INT,iOrigin)
     508{
     509        int        offset;
     510        LPMMIOINFO lpmminfo;
     511
     512//      TRACE("(%04X, %08lX, %d);\n", hmmio, lOffset, iOrigin);
     513
     514        lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
     515        if (lpmminfo == NULL)
     516                return -1;
     517
     518        offset = (iOrigin==SEEK_SET)?(lOffset - lpmminfo->lBufOffset):
     519                 (iOrigin==SEEK_CUR)?(lOffset +
     520                 (lpmminfo->pchNext - lpmminfo->pchBuffer)):-1;
     521
     522        if ((lpmminfo->cchBuffer<0)||
     523            ((offset>=0)&&(offset<=(lpmminfo->pchEndRead-lpmminfo->pchBuffer)))) {
     524                lpmminfo->pchNext = lpmminfo->pchBuffer + offset;
     525                GlobalUnlock(hmmio);
     526                return lpmminfo->lBufOffset + offset;
     527        }
     528
     529        if ((lpmminfo->fccIOProc==FOURCC_MEM)||mmioFlush(hmmio, MMIO_EMPTYBUF)) {
     530                GlobalUnlock(hmmio);
     531                return -1;
     532        }
     533
     534        offset = mmioSendMessage(hmmio, MMIOM_SEEK, (LPARAM) lOffset, (LPARAM) iOrigin);
     535        lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
     536
     537        GlobalUnlock(hmmio);
     538        return offset;
     539}
     540
     541/**************************************************************************
     542 *                              mmioGetInfo             [MMSYSTEM.1215]
     543 */
     544ODINFUNCTION3(UINT, mmioGetInfo,
     545              HMMIO,hmmio,
     546              LPMMIOINFO,lpmmioinfo,
     547              UINT,uFlags)
     548{
     549        LPMMIOINFO      lpmminfo;
     550//      TRACE("mmioGetInfo\n");
     551        lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
     552        if (lpmminfo == NULL) return 0;
     553        memcpy(lpmmioinfo, lpmminfo, sizeof(MMIOINFO));
     554        GlobalUnlock(hmmio);
     555        return 0;
     556}
     557
     558
     559/**************************************************************************
     560 *                              mmioSetInfo             [WINMM.130]
     561 */
     562ODINFUNCTION3(MMRESULT,mmioSetInfo,
     563             HMMIO, hmmio,
     564             const MMIOINFO*,lpmmioinfo,
     565             UINT,uFlags)
     566{
     567        LPMMIOINFO      lpmminfo;
     568//      TRACE("mmioSetInfo\n");
     569        lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
     570        if (lpmminfo == NULL) return 0;
     571        lpmminfo->pchNext       = lpmmioinfo->pchNext;
     572        lpmminfo->pchEndRead    = lpmmioinfo->pchEndRead;
     573        GlobalUnlock(hmmio);
     574        return 0;
     575}
     576
     577/**************************************************************************
     578*                               mmioSetBuffer           [WINMM.129]
     579*/
     580ODINFUNCTION4(UINT,mmioSetBuffer,
     581              HMMIO,hmmio,
     582              LPSTR,pchBuffer,
     583              LONG,cchBuffer,
     584              UINT,uFlags)
     585{
     586        LPMMIOINFO      lpmminfo;
     587
     588        if (mmioFlush(hmmio, MMIO_EMPTYBUF) != 0)
     589                return MMIOERR_CANNOTWRITE;
     590
     591//      TRACE("(hmmio=%04x, pchBuf=%p, cchBuf=%ld, uFlags=%#08x)\n",
     592//            hmmio, pchBuffer, cchBuffer, uFlags);
     593
     594        lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
     595        if (lpmminfo == NULL) return 0;
     596        if ((!cchBuffer || pchBuffer) && lpmminfo->dwFlags&MMIO_ALLOCBUF) {
     597                GlobalUnlock(lpmminfo->dwReserved1);
     598                GlobalFree(lpmminfo->dwReserved1);
     599                lpmminfo->dwFlags &= ~MMIO_ALLOCBUF;
     600        }
     601        if (pchBuffer) {
     602                lpmminfo->pchBuffer = pchBuffer;
     603        } else if (lpmminfo->dwFlags&MMIO_ALLOCBUF) {
     604                HGLOBAL hNewBuf;
     605                GlobalUnlock(lpmminfo->dwReserved1);
     606                hNewBuf = GlobalReAlloc(lpmminfo->dwReserved1, cchBuffer, 0);
     607                if (!hNewBuf) {
     608                        /* FIXME: this assumes the memory block didn't move */
     609                        GlobalLock(lpmminfo->dwReserved1);
     610                        GlobalUnlock(hmmio);
     611                        return MMIOERR_OUTOFMEMORY;
     612                }
     613                lpmminfo->dwReserved1 = hNewBuf;
     614                lpmminfo->pchBuffer = (LPSTR)GlobalLock(hNewBuf);
     615        } else if (cchBuffer) {
     616                HGLOBAL hNewBuf = GlobalAlloc(GMEM_MOVEABLE, cchBuffer);
     617                if (!hNewBuf) {
     618                        GlobalUnlock(hmmio);
     619                        return MMIOERR_OUTOFMEMORY;
     620                }
     621                lpmminfo->dwReserved1 = hNewBuf;
     622                lpmminfo->pchBuffer = (LPSTR)GlobalLock(hNewBuf);
     623                lpmminfo->dwFlags |= MMIO_ALLOCBUF;
     624        } else
     625                lpmminfo->pchBuffer = NULL;
     626        lpmminfo->cchBuffer = cchBuffer;
     627        lpmminfo->pchNext = lpmminfo->pchBuffer;
     628        lpmminfo->pchEndRead = lpmminfo->pchBuffer;
     629        lpmminfo->pchEndWrite = lpmminfo->pchBuffer + cchBuffer;
     630        lpmminfo->lBufOffset = 0;
     631
     632        GlobalUnlock(hmmio);
     633        return 0;
     634}
     635
     636/**************************************************************************
     637 *                              mmioFlush               [WINMM.117]
     638 */
     639ODINFUNCTION2(UINT,mmioFlush,
     640              HMMIO,hmmio,
     641              UINT,uFlags)
     642{
     643        LPMMIOINFO      lpmminfo;
     644//      TRACE("(%04X, %04X)\n", hmmio, uFlags);
     645        lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
     646        if (lpmminfo == NULL) return 0;
     647
     648        if ((!lpmminfo->cchBuffer)||(lpmminfo->fccIOProc==FOURCC_MEM)) {
     649                GlobalUnlock(hmmio);
     650                return 0;
     651        }
     652        /* not quite sure what to do here, but I'll guess */
     653        if (lpmminfo->dwFlags & MMIO_DIRTY) {
     654                mmioSendMessage(hmmio, MMIOM_SEEK,
     655                        (LPARAM) lpmminfo->lBufOffset,
     656                        (LPARAM) SEEK_SET);
     657                mmioSendMessage(hmmio, MMIOM_WRITE,
     658                        (LPARAM) lpmminfo->pchBuffer,
     659                        (LPARAM) (lpmminfo->pchNext - lpmminfo->pchBuffer) );
     660                lpmminfo->dwFlags &= ~MMIO_DIRTY;
     661        }
     662        if (uFlags & MMIO_EMPTYBUF) {
     663                /* seems Windows doesn't do any seeking here, hopefully this
     664                   won't matter, otherwise a slight rewrite is necessary */
     665                mmioSendMessage(hmmio, MMIOM_SEEK,
     666                        (LPARAM) (lpmminfo->lBufOffset +
     667                                  (lpmminfo->pchNext - lpmminfo->pchBuffer)),
     668                        (LPARAM) SEEK_SET);
     669                lpmminfo->pchNext = lpmminfo->pchBuffer;
     670                lpmminfo->pchEndRead = lpmminfo->pchBuffer;
     671                lpmminfo->lBufOffset = lpmminfo->lDiskOffset;
     672        }
     673
     674        GlobalUnlock(hmmio);
     675        return 0;
     676}
     677
     678
     679/**************************************************************************
     680 *                              mmioAdvance             [WINMM.113]
     681 */
     682ODINFUNCTION3(UINT,mmioAdvance,
     683              HMMIO, hmmio,
     684              LPMMIOINFO,lpmmioinfo,
     685              UINT,uFlags)
     686{
     687        LPMMIOINFO      lpmminfo;
     688//      TRACE("mmioAdvance\n");
     689        lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
     690        if (lpmminfo == NULL) return 0;
     691        if (!lpmminfo->cchBuffer) {
     692                GlobalUnlock(hmmio);
     693                return MMIOERR_UNBUFFERED;
     694        }
     695        lpmminfo->pchNext = lpmmioinfo->pchNext;
     696        if (mmioFlush(hmmio, MMIO_EMPTYBUF)) {
     697                GlobalUnlock(hmmio);
     698                return MMIOERR_CANNOTWRITE;
     699        }
     700        if (uFlags == MMIO_READ)
     701                lpmmioinfo->pchEndRead = lpmmioinfo->pchBuffer +
     702                    mmioSendMessage(hmmio, MMIOM_READ,
     703                        (LPARAM) lpmmioinfo->pchBuffer,
     704                        (LPARAM) lpmmioinfo->cchBuffer);
     705        lpmmioinfo->pchNext = lpmmioinfo->pchBuffer;
     706        GlobalUnlock(hmmio);
     707        return 0;
     708}
     709
     710
     711/**************************************************************************
     712 *                              mmioStringToFOURCCA     [WINMM.131]
     713 */
     714ODINFUNCTION2(FOURCC,mmioStringToFOURCCA,
     715              LPCSTR, sz, UINT, uFlags)
     716{
     717  return mmioFOURCC(sz[0],sz[1],sz[2],sz[3]);
     718}
     719
     720/**************************************************************************
     721 *                              mmioStringToFOURCCW     [WINMM.132]
     722 */
     723ODINFUNCTION2(FOURCC,mmioStringToFOURCCW,
     724              LPCWSTR, sz, UINT, uFlags)
     725{
     726        LPSTR   szA = HEAP_strdupWtoA(GetProcessHeap(),0,sz);
     727        FOURCC  ret = mmioStringToFOURCCA(szA,uFlags);
     728
     729        HeapFree(GetProcessHeap(),0,szA);
     730        return ret;
     731}
     732
     733
     734/* maximum number of I/O procedures which can be installed */
     735
     736struct IOProcList
     737{
     738  struct IOProcList *pNext;      /* Next item in linked list */
     739  FOURCC            fourCC;     /* four-character code identifying IOProc */
     740  LPMMIOPROC        pIOProc;    /* pointer to IProc */
     741};
     742
     743/* This array will be the entire list for most apps */
     744
     745static struct IOProcList defaultProcs[] = {
     746  { &defaultProcs[1], (FOURCC) FOURCC_DOS,(LPMMIOPROC) mmioDosIOProc },
     747  { NULL, (FOURCC) FOURCC_MEM,(LPMMIOPROC) mmioMemIOProc },
     748};
     749
     750static struct IOProcList *pIOProcListAnchor = &defaultProcs[0];
     751
     752ODINFUNCTION3(LPMMIOPROC, mmioInstallIOProcA,
     753              FOURCC,fccIOProc,
     754              LPMMIOPROC,pIOProc,
     755              DWORD,dwFlags)
     756{
     757        LPMMIOPROC        lpProc = NULL;
     758        struct IOProcList  *pListNode;
     759
     760//      TRACE("(%ld, %p, %08lX)\n",
     761//                               fccIOProc, pIOProc, dwFlags);
     762
     763        if (dwFlags & MMIO_GLOBALPROC) {
     764                dprintf(("WINMM: mmioInstallIOProcA global procedures not implemented\n"));
     765        }
     766
     767        /* just handle the known procedures for now */
     768        switch(dwFlags & (MMIO_INSTALLPROC|MMIO_REMOVEPROC|MMIO_FINDPROC)) {
     769                case MMIO_INSTALLPROC:
     770                  /* Create new entry for the IOProc list */
     771                  pListNode = (struct IOProcList  *)HeapAlloc(GetProcessHeap(),0,sizeof(*pListNode));
     772                  if (pListNode)
     773                  {
     774                    /* Find the end of the list, so we can add our new entry to it */
     775                    struct IOProcList *pListEnd = pIOProcListAnchor;
     776                    while (pListEnd->pNext)
     777                       pListEnd = pListEnd->pNext;
     778           
     779                    /* Fill in this node */
     780                    pListNode->fourCC = fccIOProc;
     781                    pListNode->pIOProc = pIOProc;
     782           
     783                    /* Stick it on the end of the list */
     784                    pListEnd->pNext = pListNode;
     785                    pListNode->pNext = NULL;
     786           
     787                    /* Return this IOProc - that's how the caller knows we succeeded */
     788                    lpProc = pIOProc;
     789                  }; 
     790                  break;
     791                 
     792                case MMIO_REMOVEPROC:
     793                  /*
     794                   * Search for the node that we're trying to remove - note
     795                   * that this method won't find the first item on the list, but
     796                   * since the first two items on this list are ones we won't
     797                   * let the user delete anyway, that's okay
     798                   */
     799           
     800                  pListNode = pIOProcListAnchor;
     801                  while (pListNode && pListNode->pNext->fourCC != fccIOProc)
     802                    pListNode = pListNode->pNext;
     803           
     804                  /* If we found it, remove it, but only if it isn't builtin */
     805                  if (pListNode &&
     806                      ((pListNode >= defaultProcs) && (pListNode < defaultProcs + sizeof(defaultProcs))))
     807                  {
     808                    /* Okay, nuke it */
     809                    pListNode->pNext = pListNode->pNext->pNext;
     810                    HeapFree(GetProcessHeap(),0,pListNode);
     811                  };
     812                  break;
     813           
     814                case MMIO_FINDPROC:
     815                      /* Iterate through the list looking for this proc identified by fourCC */
     816                      for (pListNode = pIOProcListAnchor; pListNode; pListNode=pListNode->pNext)
     817                      {
     818                        if (pListNode->fourCC == fccIOProc)
     819                        {
     820                          lpProc = pListNode->pIOProc;
     821                          break;
     822                        };
     823                      };
     824                      break;
     825        }
     826
     827        return lpProc;
     828}
     829
     830
     831/**************************************************************************
     832*                               mmioSendMessage         [MMSYSTEM.1222]
     833*/
     834ODINFUNCTION4(LRESULT,mmioSendMessage,
     835              HMMIO,hmmio,
     836              UINT,uMessage,
     837              LPARAM,lParam1,
     838              LPARAM,lParam2)
     839{
     840        LPMMIOINFO lpmminfo;
     841        LRESULT result;
     842        const char *msg = NULL;
     843
     844#ifdef DEBUG
     845        switch (uMessage) {
     846#define msgname(x) case x: msg = #x; break;
     847                msgname(MMIOM_OPEN);
     848                msgname(MMIOM_CLOSE);
     849                msgname(MMIOM_READ);
     850                msgname(MMIOM_WRITE);
     851                msgname(MMIOM_WRITEFLUSH);
     852                msgname(MMIOM_SEEK);
     853                msgname(MMIOM_RENAME);
     854#undef msgname
     855        }
     856#endif
     857
     858        if (msg)
     859                dprintf(("WINMM: mmioSendMessage (%04X, %s, %ld, %ld)\n",
     860                                         hmmio, msg, lParam1, lParam2));
     861        else
     862                dprintf(("WINMM: mmioSendMessage (%04X, %u, %ld, %ld)\n",
     863                                         hmmio, uMessage, lParam1, lParam2));
     864
     865        lpmminfo = (LPMMIOINFO)GlobalLock(hmmio);
     866
     867        if (lpmminfo && lpmminfo->pIOProc)
     868                result = (*lpmminfo->pIOProc)((LPSTR)lpmminfo, (UINT)uMessage, lParam1, lParam2);
     869        else
     870                result = MMSYSERR_INVALPARAM;
     871
     872        GlobalUnlock(hmmio);
     873
     874        return result;
     875}
     876
     877/**************************************************************************
     878*                               mmioDescend             [MMSYSTEM.1223]
     879*/
     880ODINFUNCTION4(UINT,mmioDescend,
     881              HMMIO,hmmio,
     882              LPMMCKINFO,lpck,
     883              const MMCKINFO *,lpckParent,
     884              UINT,uFlags)
     885{
     886        DWORD           dwOldPos;
     887        FOURCC          srchCkId;
     888        FOURCC          srchType;
     889
     890       
     891//      TRACE("(%04X, %p, %p, %04X);\n", hmmio, lpck, lpckParent, uFlags);
     892       
     893        if (lpck == NULL)
     894                return MMSYSERR_INVALPARAM;
     895       
     896        dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
     897        dprintf(("WINMM: mmioDescend - dwOldPos=%ld\n", dwOldPos));
     898       
     899        if (lpckParent != NULL) {
     900                TRACE("seek inside parent at %ld !\n", lpckParent->dwDataOffset);
     901                /* EPP: was dwOldPos = mmioSeek(hmmio,lpckParent->dwDataOffset,SEEK_SET); */
     902                if (dwOldPos < lpckParent->dwDataOffset || dwOldPos >= lpckParent->dwDataOffset + lpckParent->cksize) {
     903                dprintf(("WINMM: mmioDescend - outside parent chunk\n"));
     904                        return MMIOERR_CHUNKNOTFOUND;
     905                }
     906        }
     907       
     908        /* The SDK docu says 'ckid' is used for all cases. Real World
     909         * examples disagree -Marcus,990216.
     910         */
     911       
     912        srchType = 0;
     913        /* find_chunk looks for 'ckid' */
     914        if (uFlags & MMIO_FINDCHUNK)
     915                srchCkId = lpck->ckid;
     916        /* find_riff and find_list look for 'fccType' */
     917        if (uFlags & MMIO_FINDLIST) {
     918                srchCkId = FOURCC_LIST;
     919                srchType = lpck->fccType;
     920        }
     921        if (uFlags & MMIO_FINDRIFF) {
     922                srchCkId = FOURCC_RIFF;
     923                srchType = lpck->fccType;
     924        }
     925        dprintf(("WINMM: mmioDescend - searching for %.4s.%.4s\n",
     926              (LPSTR)&srchCkId,
     927              srchType?(LPSTR)&srchType:"<any>"));
     928       
     929        if (uFlags & (MMIO_FINDCHUNK|MMIO_FINDLIST|MMIO_FINDRIFF)) {
     930                while (TRUE) {
     931                        LONG ix;
     932                       
     933                        ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD));
     934                        if (ix < 2*sizeof(DWORD)) {
     935                                mmioSeek(hmmio, dwOldPos, SEEK_SET);
     936                                WARN("return ChunkNotFound\n");
     937                                return MMIOERR_CHUNKNOTFOUND;
     938                        }
     939                        lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
     940                        if (ix < lpck->dwDataOffset - dwOldPos) {
     941                                mmioSeek(hmmio, dwOldPos, SEEK_SET);
     942                                WARN("return ChunkNotFound\n");
     943                                return MMIOERR_CHUNKNOTFOUND;
     944                        }
     945                        dprintf(("WINMM: mmioDescend - ckid=%.4ss fcc=%.4ss cksize=%08lX !\n",
     946                              (LPSTR)&lpck->ckid,
     947                              srchType?(LPSTR)&lpck->fccType:"<unused>",
     948                              lpck->cksize));
     949                        if ((srchCkId == lpck->ckid) &&
     950                            (!srchType || (srchType == lpck->fccType))
     951                            )
     952                                break;
     953                       
     954                        dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1);
     955                        mmioSeek(hmmio, dwOldPos, SEEK_SET);
     956                }
     957        } else {
     958                /* FIXME: unverified, does it do this? */
     959                if (mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD)) < 3 * sizeof(DWORD)) {
     960                        mmioSeek(hmmio, dwOldPos, SEEK_SET);
     961                        dprintf(("WINMM: mmioDescend - return ChunkNotFound 2nd\n"));
     962                        return MMIOERR_CHUNKNOTFOUND;
     963                }
     964                lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
     965        }
     966        lpck->dwFlags = 0;
     967        /* If we were looking for RIFF/LIST chunks, the final file position
     968         * is after the chunkid. If we were just looking for the chunk
     969         * it is after the cksize. So add 4 in RIFF/LIST case.
     970         */
     971        if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST)
     972                mmioSeek(hmmio, lpck->dwDataOffset + sizeof(DWORD), SEEK_SET);
     973        else
     974                mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
     975        dprintf(("WINMM: mmioDescend - lpck: ckid=%.4s, cksize=%ld, dwDataOffset=%ld fccType=%08lX (%.4s)!\n",
     976              (LPSTR)&lpck->ckid, lpck->cksize, lpck->dwDataOffset,
     977              lpck->fccType, srchType?(LPSTR)&lpck->fccType:""));
     978        return 0;
     979}
     980
     981/**************************************************************************
     982 *                              mmioAscend              [WINMM.113]
     983 */
     984ODINFUNCTION3(UINT,mmioAscend,
     985              HMMIO,hmmio,
     986              LPMMCKINFO,lpck,
     987              UINT,uFlags)
     988{
     989//      TRACE("(%04X, %p, %04X);\n", hmmio, lpck, uFlags);
     990
     991        if (lpck->dwFlags & MMIO_DIRTY) {
     992                DWORD   dwOldPos, dwNewSize, dwSizePos;
     993               
     994                dprintf(("WINMM: mmioAscend - chunk is marked MMIO_DIRTY, correcting chunk size\n"));
     995                dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
     996                dprintf(("WINMM: mmioAscend - dwOldPos=%ld\n", dwOldPos));
     997                dwNewSize = dwOldPos - lpck->dwDataOffset;
     998                if (dwNewSize != lpck->cksize) {
     999                        TRACE("dwNewSize=%ld\n", dwNewSize);
     1000                        lpck->cksize = dwNewSize;
     1001                       
     1002                        dwSizePos = lpck->dwDataOffset - sizeof(DWORD);
     1003            dprintf(("WINMM: mmioAscend - dwSizePos=%ld\n", dwSizePos));
     1004                       
     1005                        mmioSeek(hmmio, dwSizePos, SEEK_SET);
     1006                        mmioWrite(hmmio, (LPSTR)&dwNewSize, sizeof(DWORD));
     1007                }
     1008        }
     1009
     1010        mmioSeek(hmmio, lpck->dwDataOffset + ((lpck->cksize + 1) & ~1), SEEK_SET);
     1011       
     1012        return 0;
     1013}
     1014
     1015/**************************************************************************
     1016 *                                      mmioCreateChunk                                 [WINMM.115]
     1017 */
     1018ODINFUNCTION3(UINT,mmioCreateChunk,
     1019              HMMIO,hmmio,
     1020              LPMMCKINFO,lpck,
     1021              UINT,uFlags)
     1022{
     1023        DWORD   dwOldPos;
     1024        LONG    size;
     1025        LONG    ix;
     1026
     1027//      TRACE("(%04X, %p, %04X);\n", hmmio, lpck, uFlags);
     1028
     1029        dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
     1030        dprintf(("WINMM: mmioCreateChunk - dwOldPos=%ld\n", dwOldPos));
     1031
     1032        if (uFlags == MMIO_CREATELIST)
     1033                lpck->ckid = FOURCC_LIST;
     1034        else if (uFlags == MMIO_CREATERIFF)
     1035                lpck->ckid = FOURCC_RIFF;
     1036
     1037        dprintf(("WINMM: mmioCreateChunk - ckid=%08lX\n", lpck->ckid));
     1038
     1039        size = 2 * sizeof(DWORD);
     1040        lpck->dwDataOffset = dwOldPos + size;
     1041
     1042        if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST)
     1043                size += sizeof(DWORD);
     1044        lpck->dwFlags = MMIO_DIRTY;
     1045
     1046        ix = mmioWrite(hmmio, (LPSTR)lpck, size);
     1047        TRACE("after mmioWrite ix = %ld req = %ld, errno = %d\n",ix, size, errno);
     1048        if (ix < size) {
     1049                mmioSeek(hmmio, dwOldPos, SEEK_SET);
     1050                dprintf(("WINMM: mmioCreateChunk - return CannotWrite\n"));
     1051                return MMIOERR_CANNOTWRITE;
     1052        }
     1053
     1054        return 0;
     1055}
     1056
     1057/**************************************************************************
     1058 *                              mmioRenameA                             [WINMM.125]
     1059 */
     1060ODINFUNCTION4(UINT,mmioRenameA,
     1061              LPCSTR,szFileName,
     1062              LPCSTR,szNewFileName,
     1063              LPMMIOINFO,lpmmioinfo,
     1064              DWORD,dwRenameFlags)
     1065{
     1066        UINT result;
     1067        LPMMIOINFO lpmminfo;
     1068        HMMIO hmmio;
     1069
     1070//      TRACE("('%s', '%s', %p, %08lX);\n",
     1071//                               szFileName, szNewFileName, lpmmioinfo, dwRenameFlags);
     1072        dprintf(("WINMM: This may fail - function untested\n"));
     1073        hmmio = GlobalAlloc(GHND, sizeof(MMIOINFO));
     1074        lpmminfo = (LPMMIOINFO) GlobalLock(hmmio);
     1075
     1076        if (lpmmioinfo)
     1077                memcpy(lpmminfo, lpmmioinfo, sizeof(MMIOINFO));
     1078       
     1079        /* assume DOS file if not otherwise specified */
     1080        if (lpmminfo->fccIOProc == 0 && lpmminfo->pIOProc == NULL) {
     1081
     1082                lpmminfo->fccIOProc = mmioFOURCC('D', 'O', 'S', ' ');
     1083                lpmminfo->pIOProc = (LPMMIOPROC) mmioDosIOProc;
     1084
     1085        }
     1086        /* if just the four character code is present, look up IO proc */
     1087        else if (lpmminfo->pIOProc == NULL) {
     1088
     1089                lpmminfo->pIOProc = mmioInstallIOProcA(lpmminfo->fccIOProc, NULL, MMIO_FINDPROC);
     1090
     1091        }
     1092        /* (if IO proc specified, use it and specified four character code) */
     1093
     1094        result = (UINT) mmioSendMessage(hmmio, MMIOM_RENAME, (LPARAM) szFileName, (LPARAM) szNewFileName);
     1095       
     1096        GlobalUnlock(hmmio);
     1097        GlobalFree(hmmio);
     1098
     1099        return result;
     1100}
     1101
     1102
     1103/**************************************************************************
     1104 *                              mmioRenameW                             [WINMM.126]
     1105 */
     1106ODINFUNCTION4(UINT,mmioRenameW,
     1107              LPCWSTR,szFileName,
     1108              LPCWSTR,szNewFileName,
     1109              LPMMIOINFO,lpmmioinfo,
     1110              DWORD,dwRenameFlags)
     1111{
     1112        LPSTR           szFn = HEAP_strdupWtoA(GetProcessHeap(), 0, szFileName);
     1113        LPSTR           sznFn = HEAP_strdupWtoA(GetProcessHeap(), 0, szNewFileName);
     1114        UINT    ret = mmioRenameA(szFn, sznFn, lpmmioinfo, dwRenameFlags);
     1115
     1116        HeapFree(GetProcessHeap(),0,szFn);
     1117        HeapFree(GetProcessHeap(),0,sznFn);
     1118        return ret;
    1131119}
    1141120
     
    1181124              DWORD, dwFlags)
    1191125{
     1126  // TODO: What is difference in mmioInstallIOProcW and mmioInstallIOProcA?
    1201127  dprintf(("WINMM:mmioInstallIOProcW - stub\n"));
    1211128  return 0;
    1221129}
    123 
    124 /******************************************************************************/
    125 //SvL: 24-6-'97 - Added
    126 //TODO: Not implemented
    127 /******************************************************************************/
    128 ODINFUNCTION3(HMMIO, mmioOpenA,
    129               LPTSTR, lpszFilename,
    130               LPMMIOINFO, lpmmioinfo,
    131               DWORD, fdwOpen)
    132 {
    133   dprintf(("WINMM:mmioOpenA %s - stub\n", lpszFilename));
    134   return 234;
    135 }
    136 
    137 ODINFUNCTION3(HMMIO, mmioOpenW,
    138               LPWSTR, lpszFilename,
    139               LPMMIOINFO, lpmmioinfo,
    140               DWORD, fdwOpen)
    141 {
    142   dprintf(("WINMM:mmioOpenW - stub\n"));
    143   return 234;
    144 }
    145 
    146 ODINFUNCTION3(LONG, mmioRead,
    147               HMMIO, hmmio,
    148               HPSTR, pch,
    149               LONG, cbRead)
    150 {
    151   dprintf(("WINMM:mmioRead - stub\n"));
    152   return 0;
    153 }
    154 
    155 ODINFUNCTION4(MMRESULT, mmioRenameA,
    156               LPCSTR, pszFileName,
    157               LPCSTR, pszNewFileName,
    158               LPMMIOINFO, pmmioinfo,
    159               DWORD, fdwRename)
    160 {
    161   dprintf(("WINMM:mmioRenameA - stub\n"));
    162   return 0;
    163 }
    164 
    165 ODINFUNCTION4(MMRESULT, mmioRenameW,
    166               LPCWSTR, pszFileName,
    167               LPCWSTR, pszNewFileName,
    168               LPMMIOINFO, pmmioinfo,
    169               DWORD, fdwRename)
    170 {
    171   dprintf(("WINMM:mmioRenameW - stub\n"));
    172   return 0;
    173 }
    174 
    175 ODINFUNCTION3(LONG, mmioSeek,
    176               HMMIO, hmmio,
    177               LONG, lOffset,
    178               int, nOrigin)
    179 {
    180   dprintf(("WINMM:mmioSeek - stub\n"));
    181   return(MMSYSERR_NODRIVER);
    182 }
    183 
    184 ODINFUNCTION4(LRESULT, mmioSendMessage,
    185               HMMIO, hmmio,
    186               UINT, uMsg,
    187               LPARAM, lParam1,
    188               LPARAM, lParam2)
    189 {
    190   dprintf(("WINMM:mmioSendMessage - stub\n"));
    191   return(MMSYSERR_NODRIVER);
    192 }
    193 
    194 MMRESULT WINAPI mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT fuBuffer)
    195 {
    196   dprintf(("WINMM:mmioSetBuffer - stub\n"));
    197   return(MMSYSERR_NODRIVER);
    198 }
    199 
    200 ODINFUNCTION3(MMRESULT, mmioSetInfo,
    201               HMMIO, hmmio,
    202               const MMIOINFO *, lpmmioinfo,
    203               UINT, uReserved)
    204 {
    205   dprintf(("WINMM:mmioSetInfo - stub\n"));
    206   return(MMSYSERR_NODRIVER);
    207 }
    208 
    209 
    210 /*****************************************************************************
    211 ODINFUNCTION2(*, :,
    212               FOURCC, WIN32API,
    213               OS2mmioStringToFOURCCA *, Purpose: Converts a null-terminated string to a four-character code
    214  * Parameters: LPTSTR sz
    215  *             UINT    wFlags
    216  * Variables :
    217  * Result    :
    218  * Remark    :
    219  * Status    :
    220  *
    221  * Author    : Patrick Haller [Tue, 1998/05/05 10:44]
    222  *****************************************************************************/
    223 
    224 ODINFUNCTION2(FOURCC, mmioStringToFOURCCA,
    225               LPCSTR, sz,
    226               UINT, wFlags)
    227 {
    228   union
    229   {
    230     ULONG ulFourcc;
    231     UCHAR ucFourcc[5];
    232   } unFourcc;
    233 
    234   unFourcc.ucFourcc[0] = sz[0];
    235   unFourcc.ucFourcc[1] = sz[1];
    236   unFourcc.ucFourcc[2] = sz[2];
    237   unFourcc.ucFourcc[3] = sz[3];
    238   unFourcc.ucFourcc[4] = 0;     /* string termination */
    239 
    240   if (wFlags & MMIO_TOUPPER) /* upcase the whole thing ? */
    241     strupr( (LPSTR) unFourcc.ucFourcc);
    242 
    243   dprintf(("WINMM: mmioStringToFOURCCA(%s,%08x).\n",
    244            sz,
    245            wFlags));
    246 
    247   return unFourcc.ulFourcc; /* return FOURCC */
    248 }
    249 
    250 
    251 /*****************************************************************************
    252 ODINFUNCTION2(*, :,
    253               FOURCC, WIN32API,
    254               mmioStringToFOURCCW *, Purpose: Converts a null-terminated string to a four-character code
    255  * Parameters: LPWSTR sz
    256  *             UINT    wFlags
    257  * Variables :
    258  * Result    :
    259  * Remark    :
    260  * Status    :
    261  *
    262  * Author    : Patrick Haller [Tue, 1998/05/05 10:44]
    263  *****************************************************************************/
    264 
    265 ODINFUNCTION2(FOURCC, mmioStringToFOURCCW,
    266               LPCWSTR, sz,
    267               UINT, wFlags)
    268 {
    269   union
    270   {
    271     ULONG ulFourcc;
    272     UCHAR ucFourcc[5];
    273   } unFourcc;
    274 
    275   LPSTR pszAscii;                                   /* pointer to ASCII string */
    276   UCHAR ucBuffer[5];                                    /* buffer for FOURCC */
    277 
    278   pszAscii = UnicodeToAsciiString((LPWSTR)sz);
    279 
    280   strncpy ( (LPSTR) ucBuffer,
    281            pszAscii,
    282            sizeof (ucBuffer) );
    283 
    284   FreeAsciiString(pszAscii);
    285 
    286 
    287   unFourcc.ucFourcc[0] = ucBuffer[0];
    288   unFourcc.ucFourcc[1] = ucBuffer[1];
    289   unFourcc.ucFourcc[2] = ucBuffer[2];
    290   unFourcc.ucFourcc[3] = ucBuffer[3];
    291   unFourcc.ucFourcc[4] = 0;                            /* string termination */
    292 
    293   if (wFlags & MMIO_TOUPPER)                     /* upcase the whole thing ? */
    294     strupr( (LPSTR) unFourcc.ucFourcc);
    295 
    296   dprintf(("WINMM: mmioStringToFOURCCW(%s,%08x).\n",
    297            sz,
    298            wFlags));
    299 
    300   return unFourcc.ulFourcc; /* return FOURCC */
    301 }
    302 
    303 /******************************************************************************/
    304 //SvL: 24-6-'97 - Added
    305 //TODO: Not implemented
    306 /******************************************************************************/
    307 ODINFUNCTION3(LONG, mmioWrite,
    308               HMMIO, hmmio,
    309               const char *, ch,
    310               LONG, cbWrite)
    311 {
    312   dprintf(("WINMM:mmioWrite - stub\n"));
    313   return 0;
    314 }
    315 
Note: See TracChangeset for help on using the changeset viewer.