ReactOS 0.4.15-dev-5667-ged97270
mmio.c
Go to the documentation of this file.
1/*
2 * MMIO functions
3 *
4 * Copyright 1998 Andrew Taylor
5 * Copyright 1998 Ove Kåven
6 * Copyright 2000,2002 Eric Pouech
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23/* Still to be done:
24 * + correct handling of global/local IOProcs (and temporary IOProcs)
25 * + mode of mmio objects is not used (read vs write vs readwrite)
26 * + thread safeness
27 * + 32 A <=> W message mapping
28 */
29
30#include "winemm.h"
31
33
35
36/**************************************************************************
37 * mmioDosIOProc [internal]
38 */
39static LRESULT CALLBACK mmioDosIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage,
40 LPARAM lParam1, LPARAM lParam2)
41{
43
44 TRACE("(%p, %X, 0x%lx, 0x%lx);\n", lpmmioinfo, uMessage, lParam1, lParam2);
45
46 switch (uMessage) {
47 case MMIOM_OPEN:
48 {
49 /* Parameters:
50 * lParam1 = szFileName parameter from mmioOpen
51 * lParam2 = reserved
52 * Returns: zero on success, error code on error
53 * NOTE: lDiskOffset automatically set to zero
54 */
55 LPCSTR szFileName = (LPCSTR)lParam1;
56
57 if (lpmmioinfo->dwFlags & MMIO_GETTEMP) {
58 FIXME("MMIO_GETTEMP not implemented\n");
59 return MMIOERR_CANNOTOPEN;
60 }
61
62 /* if filename NULL, assume open file handle in adwInfo[0] */
63 if (szFileName) {
64 OFSTRUCT ofs;
65 lpmmioinfo->adwInfo[0] = (DWORD)OpenFile(szFileName, &ofs, lpmmioinfo->dwFlags & 0xFFFF);
66 }
67 if (lpmmioinfo->adwInfo[0] == (DWORD)HFILE_ERROR)
69 }
70 break;
71
72 case MMIOM_CLOSE:
73 /* Parameters:
74 * lParam1 = wFlags parameter from mmioClose
75 * lParam2 = unused
76 * Returns: zero on success, error code on error
77 */
78 if (!(lParam1 & MMIO_FHOPEN))
79 _lclose((HFILE)lpmmioinfo->adwInfo[0]);
80 break;
81
82 case MMIOM_READ:
83 /* Parameters:
84 * lParam1 = huge pointer to read buffer
85 * lParam2 = number of bytes to read
86 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
87 * in wErrorRet)
88 */
89 ret = _lread((HFILE)lpmmioinfo->adwInfo[0], (HPSTR)lParam1, (LONG)lParam2);
90 if (ret != -1)
91 lpmmioinfo->lDiskOffset += ret;
92
93 break;
94
95 case MMIOM_WRITE:
97 /* no internal buffering, so WRITEFLUSH handled same as WRITE */
98
99 /* Parameters:
100 * lParam1 = huge pointer to write buffer
101 * lParam2 = number of bytes to write
102 * Returns: number of bytes written, -1 for error (error code in
103 * wErrorRet)
104 */
105 ret = _hwrite((HFILE)lpmmioinfo->adwInfo[0], (HPSTR)lParam1, (LONG)lParam2);
106 if (ret != -1)
107 lpmmioinfo->lDiskOffset += ret;
108 break;
109
110 case MMIOM_SEEK:
111 /* Parameters:
112 * lParam1 = new position
113 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
114 * Returns: new file postion, -1 on error
115 */
116 ret = _llseek((HFILE)lpmmioinfo->adwInfo[0], (LONG)lParam1, (LONG)lParam2);
117 if (ret != -1)
118 lpmmioinfo->lDiskOffset = ret;
119 return ret;
120
121 case MMIOM_RENAME:
122 /* Parameters:
123 * lParam1 = old name
124 * lParam2 = new name
125 * Returns: zero on success, non-zero on failure
126 */
127 if (!MoveFileA((const char*)lParam1, (const char*)lParam2))
129 break;
130
131 default:
132 FIXME("unexpected message %u\n", uMessage);
133 return 0;
134 }
135
136 return ret;
137}
138
139/**************************************************************************
140 * mmioMemIOProc [internal]
141 */
142static LRESULT CALLBACK mmioMemIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage,
143 LPARAM lParam1, LPARAM lParam2)
144{
145 TRACE("(%p,0x%04x,0x%08lx,0x%08lx)\n", lpmmioinfo, uMessage, lParam1, lParam2);
146
147 switch (uMessage) {
148
149 case MMIOM_OPEN:
150 /* Parameters:
151 * lParam1 = filename (must be NULL)
152 * lParam2 = reserved
153 * Returns: zero on success, error code on error
154 * NOTE: lDiskOffset automatically set to zero
155 */
156 /* FIXME: io proc shouldn't change it */
157 if (!(lpmmioinfo->dwFlags & MMIO_CREATE))
158 lpmmioinfo->pchEndRead = lpmmioinfo->pchEndWrite;
159 lpmmioinfo->adwInfo[0] = HFILE_ERROR;
160 return 0;
161
162 case MMIOM_CLOSE:
163 /* Parameters:
164 * lParam1 = wFlags parameter from mmioClose
165 * lParam2 = unused
166 * Returns: zero on success, error code on error
167 */
168 return 0;
169
170 case MMIOM_READ:
171 /* Parameters:
172 * lParam1 = huge pointer to read buffer
173 * lParam2 = number of bytes to read
174 * Returns: number of bytes read, 0 for EOF, -1 for error (error code
175 * in wErrorRet)
176 * NOTE: lDiskOffset should be updated
177 */
178 FIXME("MMIOM_READ on memory files should not occur, buffer may be lost!\n");
179 return 0;
180
181 case MMIOM_WRITE:
182 case MMIOM_WRITEFLUSH:
183 /* no internal buffering, so WRITEFLUSH handled same as WRITE */
184
185 /* Parameters:
186 * lParam1 = huge pointer to write buffer
187 * lParam2 = number of bytes to write
188 * Returns: number of bytes written, -1 for error (error code in
189 * wErrorRet)
190 * NOTE: lDiskOffset should be updated
191 */
192 FIXME("MMIOM_WRITE on memory files should not occur, buffer may be lost!\n");
193 return 0;
194
195 case MMIOM_SEEK:
196 /* Parameters:
197 * lParam1 = new position
198 * lParam2 = from whence to seek (SEEK_SET, SEEK_CUR, SEEK_END)
199 * Returns: new file postion, -1 on error
200 * NOTE: lDiskOffset should be updated
201 */
202 FIXME("MMIOM_SEEK on memory files should not occur, buffer may be lost!\n");
203 return -1;
204
205 default:
206 FIXME("unexpected message %u\n", uMessage);
207 return 0;
208 }
209}
210
211/* This array will be the entire list for most apps
212 * Note that temporary ioProcs will be stored with a 0 fourCC code
213 */
214
215static struct IOProcList defaultProcs[] = {
218};
219
221
222/****************************************************************
223 * MMIO_FindProcNode [INTERNAL]
224 *
225 * Finds the ProcList node associated with a given FOURCC code.
226 */
227static struct IOProcList* MMIO_FindProcNode(FOURCC fccIOProc)
228{
229 struct IOProcList* pListNode;
230
231 for (pListNode = pIOProcListAnchor; pListNode; pListNode = pListNode->pNext) {
232 if (pListNode->fourCC == fccIOProc) {
233 return pListNode;
234 }
235 }
236 return NULL;
237}
238
239/****************************************************************
240 * MMIO_InstallIOProc [INTERNAL]
241 */
244{
245 LPMMIOPROC lpProc = NULL;
246 struct IOProcList* pListNode;
247 struct IOProcList** ppListNode;
248
249 TRACE("(%08x, %p, %08X, %s)\n", fccIOProc, pIOProc, dwFlags, is_unicode ? "unicode" : "ansi");
250
252 FIXME("Global procedures not implemented\n");
253
254 /* just handle the known procedures for now */
256 case MMIO_INSTALLPROC:
257 /* Create new entry for the IOProc list */
258 pListNode = HeapAlloc(GetProcessHeap(), 0, sizeof(*pListNode));
259 if (pListNode) {
260 /* Fill in this node */
261 pListNode->fourCC = fccIOProc;
262 pListNode->pIOProc = pIOProc;
263 pListNode->is_unicode = is_unicode;
264 pListNode->count = 0;
265
266 /* Stick it on the end of the list */
267 pListNode->pNext = pIOProcListAnchor;
268 pIOProcListAnchor = pListNode;
269
270 /* Return this IOProc - that's how the caller knows we succeeded */
271 lpProc = pIOProc;
272 }
273 break;
274
275 case MMIO_REMOVEPROC:
276 /*
277 * Search for the node that we're trying to remove
278 * We search for a matching fourCC code if it's non null, or the proc
279 * address otherwise
280 * note that this method won't find the first item on the list, but
281 * since the first two items on this list are ones we won't
282 * let the user delete anyway, that's okay
283 */
284 ppListNode = &pIOProcListAnchor;
285 while ((*ppListNode) &&
286 ((fccIOProc != 0) ?
287 (*ppListNode)->fourCC != fccIOProc :
288 (*ppListNode)->pIOProc != pIOProc))
289 ppListNode = &((*ppListNode)->pNext);
290
291 if (*ppListNode) { /* found it */
292 /* FIXME: what should be done if an open mmio object uses this proc ?
293 * shall we return an error, nuke the mmio object ?
294 */
295 if ((*ppListNode)->count) {
296 ERR("Cannot remove a mmIOProc while in use\n");
297 break;
298 }
299 /* remove it, but only if it isn't builtin */
300 if ((*ppListNode) >= defaultProcs &&
301 (*ppListNode) < defaultProcs + sizeof(defaultProcs) / sizeof(defaultProcs[0])) {
302 WARN("Tried to remove built-in mmio proc. Skipping\n");
303 } else {
304 /* Okay, nuke it */
305 struct IOProcList* ptmpNode = *ppListNode;
306 lpProc = (*ppListNode)->pIOProc;
307 *ppListNode = (*ppListNode)->pNext;
308 HeapFree(GetProcessHeap(), 0, ptmpNode);
309 }
310 }
311 break;
312
313 case MMIO_FINDPROC:
314 if ((pListNode = MMIO_FindProcNode(fccIOProc))) {
315 lpProc = pListNode->pIOProc;
316 }
317 break;
318 }
319
320 return lpProc;
321}
322
323/****************************************************************
324 * send_message [INTERNAL]
325 */
326static LRESULT send_message(struct IOProcList* ioProc, LPMMIOINFO mmioinfo,
327 DWORD wMsg, LPARAM lParam1,
328 LPARAM lParam2, BOOL is_unicode)
329{
331 LPARAM lp1 = lParam1, lp2 = lParam2;
332
333 if (!ioProc) {
334 ERR("ioProc NULL\n");
335 return MMSYSERR_INVALPARAM;
336 }
337
338 if (ioProc->is_unicode != is_unicode) {
339 /* map (lParam1, lParam2) into (lp1, lp2) 32 A<=>W */
340 FIXME("NIY 32 A<=>W mapping\n");
341 }
342 result = (ioProc->pIOProc)((LPSTR)mmioinfo, wMsg, lp1, lp2);
343
344#if 0
345 if (ioProc->is_unicode != is_unicode) {
346 /* unmap (lParam1, lParam2) into (lp1, lp2) 32 A<=>W */
347 }
348#endif
349
350 return result;
351}
352
353/**************************************************************************
354 * MMIO_ParseExtA [internal]
355 *
356 * Parses a filename for the extension.
357 *
358 * RETURNS
359 * The FOURCC code for the extension if found, else 0.
360 */
361static FOURCC MMIO_ParseExtA(LPCSTR szFileName)
362{
363 /* Filenames are of the form file.ext{+ABC}
364 For now, we take the last '+' if present */
365
366 FOURCC ret = 0;
367
368 /* Note that ext{Start,End} point to the . and + respectively */
369 LPSTR extEnd;
370 LPSTR extStart;
371
372 TRACE("(%s)\n", debugstr_a(szFileName));
373
374 if (!szFileName)
375 return ret;
376
377 /* Find the last '.' */
378 extStart = strrchr(szFileName,'.');
379
380 if (!extStart) {
381 ERR("No . in szFileName: %s\n", debugstr_a(szFileName));
382 } else {
383 CHAR ext[5];
384
385 /* Find the '+' afterwards */
386 extEnd = strchr(extStart,'+');
387 if (extEnd) {
388
389 if (extEnd - extStart - 1 > 4)
390 WARN("Extension length > 4\n");
391 lstrcpynA(ext, extStart + 1, min(extEnd-extStart,5));
392
393 } else {
394 /* No + so just an extension */
395 if (strlen(extStart) > 4) {
396 WARN("Extension length > 4\n");
397 }
398 lstrcpynA(ext, extStart + 1, 5);
399 }
400 TRACE("Got extension: %s\n", debugstr_a(ext));
401
402 /* FOURCC codes identifying file-extensions must be uppercase */
404 }
405 return ret;
406}
407
408/**************************************************************************
409 * MMIO_Get [internal]
410 *
411 * Retrieves the mmio object from current process
412 */
413static LPWINE_MMIO MMIO_Get(HMMIO h)
414{
415 LPWINE_MMIO wm = NULL;
416
418 for (wm = MMIOList; wm; wm = wm->lpNext) {
419 if (wm->info.hmmio == h)
420 break;
421 }
423 return wm;
424}
425
426/**************************************************************************
427 * MMIO_Create [internal]
428 *
429 * Creates an internal representation for a mmio instance
430 */
432{
433 static WORD MMIO_counter = 0;
434 LPWINE_MMIO wm;
435
437 if (wm) {
439 /* lookup next unallocated WORD handle, with a non NULL value */
440 while (++MMIO_counter == 0 || MMIO_Get((HMMIO)(ULONG_PTR)MMIO_counter));
441 wm->info.hmmio = (HMMIO)(ULONG_PTR)MMIO_counter;
442 wm->lpNext = MMIOList;
443 MMIOList = wm;
445 }
446 return wm;
447}
448
449/**************************************************************************
450 * MMIO_Destroy [internal]
451 *-
452 * Destroys an internal representation for a mmio instance
453 */
455{
456 LPWINE_MMIO* m;
457
459 /* search for the matching one... */
460 m = &MMIOList;
461 while (*m && *m != wm) m = &(*m)->lpNext;
462 /* ...and destroy */
463 if (*m) {
464 *m = (*m)->lpNext;
465 HeapFree(GetProcessHeap(), 0, wm);
466 wm = NULL;
467 }
469 return wm ? FALSE : TRUE;
470}
471
472/****************************************************************
473 * MMIO_Flush [INTERNAL]
474 */
476{
477 if (wm->info.cchBuffer && (wm->info.fccIOProc != FOURCC_MEM)) {
478 /* not quite sure what to do here, but I'll guess */
479 if (wm->info.dwFlags & MMIO_DIRTY) {
480 /* FIXME: error handling */
483 (LPARAM)wm->info.pchBuffer,
484 wm->info.pchNext - wm->info.pchBuffer, FALSE);
485 }
486 if (uFlags & MMIO_EMPTYBUF)
487 wm->info.pchNext = wm->info.pchEndRead = wm->info.pchBuffer;
488 }
489 wm->info.dwFlags &= ~MMIO_DIRTY;
490
491 return MMSYSERR_NOERROR;
492}
493
494/***************************************************************************
495 * MMIO_GrabNextBuffer [INTERNAL]
496 */
497static LONG MMIO_GrabNextBuffer(LPWINE_MMIO wm, int for_read)
498{
499 LONG size = wm->info.cchBuffer;
500
501 TRACE("bo=%x do=%x of=%lx\n",
504
506 wm->info.pchNext = wm->info.pchBuffer;
507 wm->info.pchEndRead = wm->info.pchBuffer;
509
510 wm->bBufferLoaded = TRUE;
511 if (for_read) {
514 if (size > 0)
515 wm->info.pchEndRead += size;
516 else
517 wm->bBufferLoaded = FALSE;
518 }
519
520 return size;
521}
522
523/***************************************************************************
524 * MMIO_SetBuffer [INTERNAL]
525 */
526static MMRESULT MMIO_SetBuffer(WINE_MMIO* wm, void* pchBuffer, LONG cchBuffer,
527 UINT uFlags)
528{
529 TRACE("(%p %p %d %u)\n", wm, pchBuffer, cchBuffer, uFlags);
530
531 if (cchBuffer > 0xFFFF)
532 WARN("Untested handling of huge mmio buffers (%d >= 64k)\n", cchBuffer);
533
534 if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
535 return MMIOERR_CANNOTWRITE;
536
537 /* free previous buffer if allocated */
538 if (wm->info.dwFlags & MMIO_ALLOCBUF) {
540 wm->info.pchBuffer = NULL;
541 wm->info.dwFlags &= ~MMIO_ALLOCBUF;
542 }
543
544 if (pchBuffer) {
545 wm->info.pchBuffer = pchBuffer;
546 } else if (cchBuffer) {
547 if (!(wm->info.pchBuffer = HeapAlloc(GetProcessHeap(), 0, cchBuffer)))
548 return MMIOERR_OUTOFMEMORY;
550 } else {
551 wm->info.pchBuffer = NULL;
552 }
553
555 wm->info.pchNext = wm->info.pchBuffer;
556 wm->info.pchEndRead = wm->info.pchBuffer;
559 wm->bBufferLoaded = FALSE;
560
561 return MMSYSERR_NOERROR;
562}
563
564/**************************************************************************
565 * MMIO_Open [internal]
566 */
567static HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO* refmminfo, DWORD dwOpenFlags, BOOL is_unicode)
568{
569 LPWINE_MMIO wm;
570 MMIOINFO mmioinfo;
571
572 TRACE("('%s', %p, %08X, %s);\n", szFileName, refmminfo, dwOpenFlags, is_unicode ? "unicode" : "ansi");
573
574 if (!refmminfo) {
575 refmminfo = &mmioinfo;
576
577 mmioinfo.fccIOProc = 0;
578 mmioinfo.pIOProc = NULL;
579 mmioinfo.pchBuffer = NULL;
580 mmioinfo.cchBuffer = 0;
582 }
583
584 if (dwOpenFlags & (MMIO_PARSE|MMIO_EXIST)) {
585 char buffer[MAX_PATH];
586
587 if (!szFileName)
588 return (HMMIO)FALSE;
589 if (GetFullPathNameA(szFileName, sizeof(buffer), buffer, NULL) >= sizeof(buffer))
590 return (HMMIO)FALSE;
591 if ((dwOpenFlags & MMIO_EXIST) && (GetFileAttributesA(buffer) == INVALID_FILE_ATTRIBUTES))
592 return (HMMIO)FALSE;
593 strcpy(szFileName, buffer);
594 return (HMMIO)TRUE;
595 }
596
597 if ((wm = MMIO_Create()) == NULL)
598 return 0;
599
600 /* If both params are NULL, then parse the file name if available */
601 if (refmminfo->fccIOProc == 0 && refmminfo->pIOProc == NULL) {
602 wm->info.fccIOProc = MMIO_ParseExtA(szFileName);
603 /* Handle any unhandled/error case. Assume DOS file */
604 if (wm->info.fccIOProc == 0)
606 if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) {
607 /* If not found, retry with FOURCC_DOS */
609 if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc)))
610 goto error2;
611 }
612 wm->bTmpIOProc = FALSE;
613 }
614 /* if just the four character code is present, look up IO proc */
615 else if (refmminfo->pIOProc == NULL) {
616 wm->info.fccIOProc = refmminfo->fccIOProc;
617 if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) goto error2;
618 wm->bTmpIOProc = FALSE;
619 }
620 /* if IO proc specified, use it and specified four character code */
621 else {
622 wm->info.fccIOProc = refmminfo->fccIOProc;
625 if (!(wm->ioProc = MMIO_FindProcNode(wm->info.fccIOProc))) goto error2;
626 assert(wm->ioProc->pIOProc == refmminfo->pIOProc);
627 wm->bTmpIOProc = TRUE;
628 }
629
630 wm->ioProc->count++;
631 wm->info.dwFlags = dwOpenFlags;
632
633 if (dwOpenFlags & MMIO_ALLOCBUF) {
634 refmminfo->wErrorRet = MMIO_SetBuffer(wm, refmminfo->pchBuffer,
635 refmminfo->cchBuffer ? refmminfo->cchBuffer : MMIO_DEFAULTBUFFER, 0);
636 if (refmminfo->wErrorRet != MMSYSERR_NOERROR)
637 goto error1;
638 } else {
639 refmminfo->wErrorRet = MMIO_SetBuffer(wm, refmminfo->pchBuffer, refmminfo->cchBuffer, 0);
640 if (refmminfo->wErrorRet != MMSYSERR_NOERROR)
641 goto error1;
642 }
643
644 if (wm->info.fccIOProc == FOURCC_MEM && !(wm->info.dwFlags & MMIO_ALLOCBUF))
645 wm->bBufferLoaded = TRUE;
646
647 /* see mmioDosIOProc for that one */
648 wm->info.adwInfo[0] = refmminfo->adwInfo[0];
649
650 /* call IO proc to actually open file */
651 refmminfo->wErrorRet = send_message(wm->ioProc, &wm->info, MMIOM_OPEN,
652 (LPARAM)szFileName, 0, FALSE);
653
654 /* grab file size, when possible (FIXME: not 64 bit safe) */
656
657 if (refmminfo->wErrorRet == 0)
658 return wm->info.hmmio;
659 error1:
660 if (wm->ioProc) wm->ioProc->count--;
661 error2:
662 MMIO_Destroy(wm);
663 return 0;
664}
665
666/**************************************************************************
667 * mmioOpenW [WINMM.@]
668 */
669HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO* lpmmioinfo,
670 DWORD dwOpenFlags)
671{
672 HMMIO ret;
673 LPSTR szFn = NULL;
674
675 if (szFileName)
676 {
677 INT len = WideCharToMultiByte( CP_ACP, 0, szFileName, -1, NULL, 0, NULL, NULL );
678 szFn = HeapAlloc( GetProcessHeap(), 0, len );
679 if (!szFn) return NULL;
680 WideCharToMultiByte( CP_ACP, 0, szFileName, -1, szFn, len, NULL, NULL );
681 }
682
683 ret = MMIO_Open(szFn, lpmmioinfo, dwOpenFlags, TRUE);
684
685 HeapFree(GetProcessHeap(), 0, szFn);
686 return ret;
687}
688
689/**************************************************************************
690 * mmioOpenA [WINMM.@]
691 */
692HMMIO WINAPI mmioOpenA(LPSTR szFileName, MMIOINFO* lpmmioinfo,
693 DWORD dwOpenFlags)
694{
695 return MMIO_Open(szFileName, lpmmioinfo, dwOpenFlags, FALSE);
696}
697
698/**************************************************************************
699 * mmioClose [WINMM.@]
700 */
702{
703 LPWINE_MMIO wm;
705
706 TRACE("(%p, %04X);\n", hmmio, uFlags);
707
708 if ((wm = MMIO_Get(hmmio)) == NULL)
710
711 if ((result = MMIO_Flush(wm, 0)) != MMSYSERR_NOERROR)
712 return result;
713
715
716 MMIO_SetBuffer(wm, NULL, 0, 0);
717
718 wm->ioProc->count--;
719
720 if (wm->bTmpIOProc)
721 MMIO_InstallIOProc(wm->info.fccIOProc, wm->ioProc->pIOProc,
722 MMIO_REMOVEPROC, wm->ioProc->is_unicode);
723
724 MMIO_Destroy(wm);
725
726 return result;
727}
728
729/**************************************************************************
730 * mmioRead [WINMM.@]
731 */
733{
734 LPWINE_MMIO wm;
735 LONG count;
736
737 TRACE("(%p, %p, %d);\n", hmmio, pch, cch);
738
739 if ((wm = MMIO_Get(hmmio)) == NULL)
740 return -1;
741
742 /* unbuffered case first */
743 if (!wm->info.pchBuffer)
744 return send_message(wm->ioProc, &wm->info, MMIOM_READ, (LPARAM)pch, cch, FALSE);
745
746 /* first try from current buffer */
747 if (wm->info.pchNext != wm->info.pchEndRead) {
748 count = wm->info.pchEndRead - wm->info.pchNext;
749 if (count > cch || count < 0) count = cch;
750 memcpy(pch, wm->info.pchNext, count);
751 wm->info.pchNext += count;
752 pch += count;
753 cch -= count;
754 } else
755 count = 0;
756
757 if (cch && (wm->info.fccIOProc != FOURCC_MEM)) {
758 assert(wm->info.cchBuffer);
759
760 while (cch) {
761 LONG size;
762
764 if (size <= 0) break;
765 if (size > cch) size = cch;
767 wm->info.pchNext += size;
768 pch += size;
769 cch -= size;
770 count += size;
771 }
772 }
773
774 TRACE("count=%d\n", count);
775 return count;
776}
777
778/**************************************************************************
779 * mmioWrite [WINMM.@]
780 */
781LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
782{
783 LPWINE_MMIO wm;
784 LONG count;
785
786 TRACE("(%p, %p, %d);\n", hmmio, pch, cch);
787
788 if ((wm = MMIO_Get(hmmio)) == NULL)
789 return -1;
790
791 if (wm->info.cchBuffer) {
792 LONG bytesW = 0;
793
794 count = 0;
795 while (cch) {
796 if (wm->info.pchNext != wm->info.pchEndWrite) {
797 count = wm->info.pchEndWrite - wm->info.pchNext;
798 if (count > cch || count < 0) count = cch;
799 memcpy(wm->info.pchNext, pch, count);
800 wm->info.pchNext += count;
801 pch += count;
802 cch -= count;
803 bytesW += count;
804 wm->info.dwFlags |= MMIO_DIRTY;
805 } else {
806 if (wm->info.fccIOProc == FOURCC_MEM) {
807 if (wm->info.adwInfo[0]) {
808 /* from where would we get the memory handle? */
809 FIXME("memory file expansion not implemented!\n");
810 break;
811 } else break;
812 }
813 }
814
815 if (wm->info.pchNext == wm->info.pchEndWrite)
816 {
819 }
820 else break;
821 }
822 count = bytesW;
823 } else {
826 }
827
828 TRACE("bytes written=%d\n", count);
829 return count;
830}
831
832/**************************************************************************
833 * mmioSeek [WINMM.@]
834 */
835LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
836{
837 LPWINE_MMIO wm;
838 LONG offset;
839
840 TRACE("(%p, %08X, %d);\n", hmmio, lOffset, iOrigin);
841
842 if ((wm = MMIO_Get(hmmio)) == NULL)
844
845 /* not buffered, direct seek on file */
846 if (!wm->info.pchBuffer)
847 return send_message(wm->ioProc, &wm->info, MMIOM_SEEK, lOffset, iOrigin, FALSE);
848
849 switch (iOrigin) {
850 case SEEK_SET:
851 offset = lOffset;
852 break;
853 case SEEK_CUR:
854 offset = wm->info.lBufOffset + (wm->info.pchNext - wm->info.pchBuffer) + lOffset;
855 break;
856 case SEEK_END:
857 offset = ((wm->info.fccIOProc == FOURCC_MEM)? wm->info.cchBuffer : wm->dwFileSize) - lOffset;
858 break;
859 default:
860 return -1;
861 }
862
863 if (offset && offset >= wm->dwFileSize && wm->info.fccIOProc != FOURCC_MEM) {
864 /* should check that write mode exists */
865 if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
866 return -1;
867 wm->info.lBufOffset = offset;
868 wm->info.pchEndRead = wm->info.pchBuffer;
870 if ((wm->info.dwFlags & MMIO_RWMODE) == MMIO_READ) {
871 wm->info.lDiskOffset = wm->dwFileSize;
872 }
873 } else if ((wm->info.cchBuffer > 0) &&
874 ((offset < wm->info.lBufOffset) ||
875 (offset >= wm->info.lBufOffset + wm->info.cchBuffer) ||
876 !wm->bBufferLoaded)) {
877 /* stay in same buffer ? */
878 /* some memory mapped buffers are defined with -1 as a size */
879
880 /* condition to change buffer */
881 if ((wm->info.fccIOProc == FOURCC_MEM) ||
882 MMIO_Flush(wm, 0) != MMSYSERR_NOERROR ||
883 /* this also sets the wm->info.lDiskOffset field */
885 (offset / wm->info.cchBuffer) * wm->info.cchBuffer,
886 SEEK_SET, FALSE) == -1)
887 return -1;
889 }
890
891 wm->info.pchNext = wm->info.pchBuffer + (offset - wm->info.lBufOffset);
892
893 TRACE("=> %d\n", offset);
894 return offset;
895}
896
897/**************************************************************************
898 * mmioGetInfo [WINMM.@]
899 */
900MMRESULT WINAPI mmioGetInfo(HMMIO hmmio, MMIOINFO* lpmmioinfo, UINT uFlags)
901{
902 LPWINE_MMIO wm;
903
904 TRACE("(%p,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
905
906 if ((wm = MMIO_Get(hmmio)) == NULL)
908
909 *lpmmioinfo = wm->info;
910
911 return MMSYSERR_NOERROR;
912}
913
914/**************************************************************************
915 * mmioSetInfo [WINMM.@]
916 */
917MMRESULT WINAPI mmioSetInfo(HMMIO hmmio, const MMIOINFO* lpmmioinfo, UINT uFlags)
918{
919 LPWINE_MMIO wm;
920
921 TRACE("(%p,%p,0x%08x)\n",hmmio,lpmmioinfo,uFlags);
922
923 if ((wm = MMIO_Get(hmmio)) == NULL)
925
926 /* check pointers coherence */
927 if (lpmmioinfo->pchNext < wm->info.pchBuffer ||
928 lpmmioinfo->pchNext > wm->info.pchBuffer + wm->info.cchBuffer ||
929 lpmmioinfo->pchEndRead < wm->info.pchBuffer ||
930 lpmmioinfo->pchEndRead > wm->info.pchBuffer + wm->info.cchBuffer ||
931 lpmmioinfo->pchEndWrite < wm->info.pchBuffer ||
932 lpmmioinfo->pchEndWrite > wm->info.pchBuffer + wm->info.cchBuffer)
933 return MMSYSERR_INVALPARAM;
934
935 wm->info.pchNext = lpmmioinfo->pchNext;
936 wm->info.pchEndRead = lpmmioinfo->pchEndRead;
937
938 return MMSYSERR_NOERROR;
939}
940
941/**************************************************************************
942* mmioSetBuffer [WINMM.@]
943*/
945{
946 LPWINE_MMIO wm;
947
948 TRACE("(hmmio=%p, pchBuf=%p, cchBuf=%d, uFlags=%#08x)\n",
949 hmmio, pchBuffer, cchBuffer, uFlags);
950
951 if ((wm = MMIO_Get(hmmio)) == NULL)
953
954 return MMIO_SetBuffer(wm, pchBuffer, cchBuffer, uFlags);
955}
956
957/**************************************************************************
958 * mmioFlush [WINMM.@]
959 */
961{
962 LPWINE_MMIO wm;
963
964 TRACE("(%p, %04X)\n", hmmio, uFlags);
965
966 if ((wm = MMIO_Get(hmmio)) == NULL)
968
969 return MMIO_Flush(wm, uFlags);
970}
971
972/**************************************************************************
973 * mmioAdvance [WINMM.@]
974 */
975MMRESULT WINAPI mmioAdvance(HMMIO hmmio, MMIOINFO* lpmmioinfo, UINT uFlags)
976{
977 LPWINE_MMIO wm;
978
979 TRACE("hmmio=%p, lpmmioinfo=%p, uFlags=%04X\n", hmmio, lpmmioinfo, uFlags);
980
981 /* NOTE: mmioAdvance16 heavily relies on parameters from lpmmioinfo we're using
982 * here. be sure if you change something here to check mmioAdvance16 as well
983 */
984 if ((wm = MMIO_Get(hmmio)) == NULL)
986
987 if (!wm->info.cchBuffer)
988 return MMIOERR_UNBUFFERED;
989
990 if (uFlags != MMIO_READ && uFlags != MMIO_WRITE)
991 return MMSYSERR_INVALPARAM;
992
993 if (uFlags == MMIO_WRITE && (lpmmioinfo->dwFlags & MMIO_DIRTY))
994 {
995 send_message(wm->ioProc, &wm->info, MMIOM_SEEK, lpmmioinfo->lBufOffset, SEEK_SET, FALSE);
996 send_message(wm->ioProc, &wm->info, MMIOM_WRITE, (LPARAM)lpmmioinfo->pchBuffer,
997 lpmmioinfo->pchNext - lpmmioinfo->pchBuffer, FALSE);
998 lpmmioinfo->dwFlags &= ~MMIO_DIRTY;
999 }
1000 if (MMIO_Flush(wm, 0) != MMSYSERR_NOERROR)
1001 return MMIOERR_CANNOTWRITE;
1002
1003 if (lpmmioinfo) {
1004 wm->dwFileSize = max(wm->dwFileSize, lpmmioinfo->lBufOffset +
1005 (lpmmioinfo->pchNext - lpmmioinfo->pchBuffer));
1006 }
1008
1009 if (lpmmioinfo) {
1010 lpmmioinfo->pchNext = lpmmioinfo->pchBuffer;
1011 lpmmioinfo->pchEndRead = lpmmioinfo->pchBuffer +
1012 (wm->info.pchEndRead - wm->info.pchBuffer);
1013 lpmmioinfo->pchEndWrite = lpmmioinfo->pchBuffer +
1014 (wm->info.pchEndWrite - wm->info.pchBuffer);
1015 lpmmioinfo->lDiskOffset = wm->info.lDiskOffset;
1016 lpmmioinfo->lBufOffset = wm->info.lBufOffset;
1017 }
1018 return MMSYSERR_NOERROR;
1019}
1020
1021/**************************************************************************
1022 * mmioStringToFOURCCA [WINMM.@]
1023 */
1025{
1026 CHAR cc[4];
1027 int i = 0;
1028
1029 for (i = 0; i < 4 && sz[i]; i++) {
1030 if (uFlags & MMIO_TOUPPER) {
1031 cc[i] = toupper(sz[i]);
1032 } else {
1033 cc[i] = sz[i];
1034 }
1035 }
1036
1037 /* Pad with spaces */
1038 while (i < 4) cc[i++] = ' ';
1039
1040 TRACE("Got '%.4s'\n",cc);
1041 return mmioFOURCC(cc[0],cc[1],cc[2],cc[3]);
1042}
1043
1044/**************************************************************************
1045 * mmioStringToFOURCCW [WINMM.@]
1046 */
1048{
1049 char szA[4];
1050
1051 WideCharToMultiByte( CP_ACP, 0, sz, 4, szA, sizeof(szA), NULL, NULL );
1052 return mmioStringToFOURCCA(szA,uFlags);
1053}
1054
1055/**************************************************************************
1056 * mmioInstallIOProcA [WINMM.@]
1057 */
1060{
1061 return MMIO_InstallIOProc(fccIOProc, pIOProc, dwFlags, FALSE);
1062}
1063
1064/**************************************************************************
1065 * mmioInstallIOProcW [WINMM.@]
1066 */
1069{
1070 return MMIO_InstallIOProc(fccIOProc, pIOProc, dwFlags, TRUE);
1071}
1072
1073/******************************************************************
1074 * MMIO_SendMessage
1075 *
1076 *
1077 */
1078static LRESULT MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1,
1079 LPARAM lParam2, BOOL is_unicode)
1080{
1081 LPWINE_MMIO wm;
1082
1083 TRACE("(%p, %u, %ld, %ld, %s)\n", hmmio, uMessage, lParam1, lParam2, is_unicode ? "unicode" : "ansi");
1084
1085 if (uMessage < MMIOM_USER)
1086 return MMSYSERR_INVALPARAM;
1087
1088 if ((wm = MMIO_Get(hmmio)) == NULL)
1089 return MMSYSERR_INVALHANDLE;
1090
1091 return send_message(wm->ioProc, &wm->info, uMessage, lParam1, lParam2, is_unicode);
1092}
1093
1094/**************************************************************************
1095 * mmioSendMessage [WINMM.@]
1096 */
1097LRESULT WINAPI mmioSendMessage(HMMIO hmmio, UINT uMessage,
1098 LPARAM lParam1, LPARAM lParam2)
1099{
1100 return MMIO_SendMessage(hmmio, uMessage, lParam1, lParam2, FALSE);
1101}
1102
1103/**************************************************************************
1104 * mmioDescend [WINMM.@]
1105 */
1107 const MMCKINFO* lpckParent, UINT uFlags)
1108{
1109 DWORD dwOldPos;
1110 FOURCC srchCkId;
1111 FOURCC srchType;
1112
1113 TRACE("(%p, %p, %p, %04X);\n", hmmio, lpck, lpckParent, uFlags);
1114
1115 if (lpck == NULL)
1116 return MMSYSERR_INVALPARAM;
1117
1118 dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
1119 TRACE("dwOldPos=%d\n", dwOldPos);
1120
1121 if (lpckParent != NULL) {
1122 TRACE("seek inside parent at %d !\n", lpckParent->dwDataOffset);
1123 /* EPP: was dwOldPos = mmioSeek(hmmio,lpckParent->dwDataOffset,SEEK_SET); */
1124 if (dwOldPos < lpckParent->dwDataOffset ||
1125 dwOldPos >= lpckParent->dwDataOffset + lpckParent->cksize) {
1126 WARN("outside parent chunk\n");
1127 return MMIOERR_CHUNKNOTFOUND;
1128 }
1129 }
1130
1131 /* The SDK docu says 'ckid' is used for all cases. Real World
1132 * examples disagree -Marcus,990216.
1133 */
1134
1135 srchCkId = 0;
1136 srchType = 0;
1137
1138 /* find_chunk looks for 'ckid' */
1139 if (uFlags & MMIO_FINDCHUNK)
1140 srchCkId = lpck->ckid;
1141
1142 /* find_riff and find_list look for 'fccType' */
1143 if (uFlags & MMIO_FINDLIST)
1144 {
1145 srchCkId = FOURCC_LIST;
1146 srchType = lpck->fccType;
1147 }
1148
1149 if (uFlags & MMIO_FINDRIFF)
1150 {
1151 srchCkId = FOURCC_RIFF;
1152 srchType = lpck->fccType;
1153 }
1154
1155 TRACE("searching for %4.4s.%4.4s\n",
1156 (LPCSTR)&srchCkId, srchType ? (LPCSTR)&srchType : "any");
1157
1158 while (TRUE)
1159 {
1160 LONG ix;
1161
1162 ix = mmioRead(hmmio, (LPSTR)lpck, 3 * sizeof(DWORD));
1163 if (ix < 2*sizeof(DWORD))
1164 {
1165 mmioSeek(hmmio, dwOldPos, SEEK_SET);
1166 WARN("return ChunkNotFound\n");
1167 return MMIOERR_CHUNKNOTFOUND;
1168 }
1169
1170 lpck->dwDataOffset = dwOldPos + 2 * sizeof(DWORD);
1171 TRACE("ckid=%4.4s fcc=%4.4s cksize=%08X !\n",
1172 (LPCSTR)&lpck->ckid,
1173 srchType ? (LPCSTR)&lpck->fccType:"<na>",
1174 lpck->cksize);
1175 if ( (!srchCkId || (srchCkId == lpck->ckid)) &&
1176 (!srchType || (srchType == lpck->fccType)) )
1177 break;
1178
1179 dwOldPos = lpck->dwDataOffset + ((lpck->cksize + 1) & ~1);
1180 mmioSeek(hmmio, dwOldPos, SEEK_SET);
1181 }
1182
1183 lpck->dwFlags = 0;
1184 /* If we were looking for RIFF/LIST chunks, the final file position
1185 * is after the chunkid. If we were just looking for the chunk
1186 * it is after the cksize. So add 4 in RIFF/LIST case.
1187 */
1188 if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST)
1189 mmioSeek(hmmio, lpck->dwDataOffset + sizeof(DWORD), SEEK_SET);
1190 else
1191 {
1192 mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET);
1193 lpck->fccType = 0;
1194 }
1195 TRACE("lpck: ckid=%.4s, cksize=%d, dwDataOffset=%d fccType=%08X (%.4s)!\n",
1196 (LPSTR)&lpck->ckid, lpck->cksize, lpck->dwDataOffset,
1197 lpck->fccType, srchType?(LPSTR)&lpck->fccType:"");
1198 return MMSYSERR_NOERROR;
1199}
1200
1201/**************************************************************************
1202 * mmioAscend [WINMM.@]
1203 */
1205{
1206 TRACE("(%p, %p, %04X);\n", hmmio, lpck, uFlags);
1207
1208 if (lpck->dwFlags & MMIO_DIRTY) {
1209 DWORD dwOldPos, dwNewSize;
1210
1211 TRACE("Chunk is dirty, checking if chunk's size is correct\n");
1212 dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
1213 TRACE("dwOldPos=%d lpck->dwDataOffset = %d\n", dwOldPos, lpck->dwDataOffset);
1214 dwNewSize = dwOldPos - lpck->dwDataOffset;
1215 if (dwNewSize != lpck->cksize) {
1216 TRACE("Nope: lpck->cksize=%d dwNewSize=%d\n", lpck->cksize, dwNewSize);
1217 lpck->cksize = dwNewSize;
1218
1219 /* pad odd size with 0 */
1220 if (dwNewSize & 1) {
1221 char ch = 0;
1222 mmioWrite(hmmio, &ch, 1);
1223 }
1224 mmioSeek(hmmio, lpck->dwDataOffset - sizeof(DWORD), SEEK_SET);
1225 mmioWrite(hmmio, (LPSTR)&dwNewSize, sizeof(DWORD));
1226 }
1227 lpck->dwFlags = 0;
1228 }
1229
1230 mmioSeek(hmmio, lpck->dwDataOffset + ((lpck->cksize + 1) & ~1), SEEK_SET);
1231
1232 return MMSYSERR_NOERROR;
1233}
1234
1235/**************************************************************************
1236 * mmioCreateChunk [WINMM.@]
1237 */
1239{
1240 DWORD dwOldPos;
1241 LONG size;
1242 LONG ix;
1243
1244 TRACE("(%p, %p, %04X);\n", hmmio, lpck, uFlags);
1245
1246 dwOldPos = mmioSeek(hmmio, 0, SEEK_CUR);
1247 TRACE("dwOldPos=%d\n", dwOldPos);
1248
1249 if (uFlags == MMIO_CREATELIST)
1250 lpck->ckid = FOURCC_LIST;
1251 else if (uFlags == MMIO_CREATERIFF)
1252 lpck->ckid = FOURCC_RIFF;
1253
1254 TRACE("ckid=%.4s\n", (LPSTR)&lpck->ckid);
1255
1256 size = 2 * sizeof(DWORD);
1257 lpck->dwDataOffset = dwOldPos + size;
1258
1259 if (lpck->ckid == FOURCC_RIFF || lpck->ckid == FOURCC_LIST)
1260 size += sizeof(DWORD);
1261 lpck->dwFlags = MMIO_DIRTY;
1262
1263 ix = mmioWrite(hmmio, (LPSTR)lpck, size);
1264 TRACE("after mmioWrite ix = %d req = %d, errno = %d\n", ix, size, errno);
1265 if (ix < size) {
1266 mmioSeek(hmmio, dwOldPos, SEEK_SET);
1267 WARN("return CannotWrite\n");
1268 return MMIOERR_CANNOTWRITE;
1269 }
1270
1271 return MMSYSERR_NOERROR;
1272}
1273
1274/**************************************************************************
1275 * mmioRenameA [WINMM.@]
1276 */
1277MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName,
1278 const MMIOINFO* lpmmioinfo, DWORD dwFlags)
1279{
1280 struct IOProcList* ioProc = NULL;
1281 struct IOProcList tmp;
1282 FOURCC fcc;
1283
1284 TRACE("('%s', '%s', %p, %08X);\n",
1285 debugstr_a(szFileName), debugstr_a(szNewFileName), lpmmioinfo, dwFlags);
1286
1287 /* If both params are NULL, then parse the file name */
1288 if (lpmmioinfo && lpmmioinfo->fccIOProc == 0 && lpmmioinfo->pIOProc == NULL)
1289 {
1290 fcc = MMIO_ParseExtA(szFileName);
1291 if (fcc) ioProc = MMIO_FindProcNode(fcc);
1292 }
1293
1294 /* Handle any unhandled/error case from above. Assume DOS file */
1295 if (!lpmmioinfo || (lpmmioinfo->fccIOProc == 0 && lpmmioinfo->pIOProc == NULL && ioProc == NULL))
1296 ioProc = MMIO_FindProcNode(FOURCC_DOS);
1297 /* if just the four character code is present, look up IO proc */
1298 else if (lpmmioinfo->pIOProc == NULL)
1299 ioProc = MMIO_FindProcNode(lpmmioinfo->fccIOProc);
1300 else /* use relevant ioProc */
1301 {
1302 ioProc = &tmp;
1303 tmp.fourCC = lpmmioinfo->fccIOProc;
1304 tmp.pIOProc = lpmmioinfo->pIOProc;
1305 tmp.is_unicode = FALSE;
1306 tmp.count = 1;
1307 }
1308
1309 /* FIXME: should we actually pass lpmmioinfo down the drain ???
1310 * or make a copy of it because it's const ???
1311 */
1312 return send_message(ioProc, (MMIOINFO*)lpmmioinfo, MMIOM_RENAME,
1313 (LPARAM)szFileName, (LPARAM)szNewFileName, FALSE);
1314}
1315
1316/**************************************************************************
1317 * mmioRenameW [WINMM.@]
1318 */
1319MMRESULT WINAPI mmioRenameW(LPCWSTR szFileName, LPCWSTR szNewFileName,
1320 const MMIOINFO* lpmmioinfo, DWORD dwFlags)
1321{
1322 LPSTR szFn = NULL;
1323 LPSTR sznFn = NULL;
1325 INT len;
1326
1327 if (szFileName)
1328 {
1329 len = WideCharToMultiByte( CP_ACP, 0, szFileName, -1, NULL, 0, NULL, NULL );
1330 szFn = HeapAlloc( GetProcessHeap(), 0, len );
1331 if (!szFn) goto done;
1332 WideCharToMultiByte( CP_ACP, 0, szFileName, -1, szFn, len, NULL, NULL );
1333 }
1334 if (szNewFileName)
1335 {
1336 len = WideCharToMultiByte( CP_ACP, 0, szNewFileName, -1, NULL, 0, NULL, NULL );
1337 sznFn = HeapAlloc( GetProcessHeap(), 0, len );
1338 if (!sznFn) goto done;
1339 WideCharToMultiByte( CP_ACP, 0, szNewFileName, -1, sznFn, len, NULL, NULL );
1340 }
1341
1342 ret = mmioRenameA(szFn, sznFn, lpmmioinfo, dwFlags);
1343
1344done:
1345 HeapFree(GetProcessHeap(),0,szFn);
1346 HeapFree(GetProcessHeap(),0,sznFn);
1347 return ret;
1348}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int toupper(int c)
Definition: utclib.c:881
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define SEEK_END
Definition: cabinet.c:27
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT uFlags
Definition: api.c:59
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define lstrcpynA
Definition: compat.h:751
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR *const ext[]
Definition: module.c:53
static DWORD cchBuffer
Definition: fusion.c:85
HFILE WINAPI OpenFile(LPCSTR lpFileName, LPOFSTRUCT lpReOpenBuff, UINT uStyle)
Definition: create.c:368
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:636
BOOL WINAPI MoveFileA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName)
Definition: move.c:1137
DWORD WINAPI GetFullPathNameA(IN LPCSTR lpFileName, IN DWORD nBufferLength, OUT LPSTR lpBuffer, OUT LPSTR *lpFilePart)
Definition: path.c:993
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1204
static HMMIO MMIO_Open(LPSTR szFileName, MMIOINFO *refmminfo, DWORD dwOpenFlags, BOOL is_unicode)
Definition: mmio.c:567
static MMRESULT MMIO_Flush(WINE_MMIO *wm, UINT uFlags)
Definition: mmio.c:475
static LPMMIOPROC MMIO_InstallIOProc(FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags, BOOL is_unicode)
Definition: mmio.c:242
MMRESULT WINAPI mmioSetBuffer(HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT uFlags)
Definition: mmio.c:944
static LONG MMIO_GrabNextBuffer(LPWINE_MMIO wm, int for_read)
Definition: mmio.c:497
MMRESULT WINAPI mmioFlush(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:960
static LRESULT MMIO_SendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1, LPARAM lParam2, BOOL is_unicode)
Definition: mmio.c:1078
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:835
MMRESULT WINAPI mmioGetInfo(HMMIO hmmio, MMIOINFO *lpmmioinfo, UINT uFlags)
Definition: mmio.c:900
HMMIO WINAPI mmioOpenA(LPSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:692
static FOURCC MMIO_ParseExtA(LPCSTR szFileName)
Definition: mmio.c:361
static LRESULT CALLBACK mmioDosIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage, LPARAM lParam1, LPARAM lParam2)
Definition: mmio.c:39
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:701
LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
Definition: mmio.c:781
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1106
static struct IOProcList * pIOProcListAnchor
Definition: mmio.c:220
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:732
static struct IOProcList defaultProcs[]
Definition: mmio.c:215
FOURCC WINAPI mmioStringToFOURCCW(LPCWSTR sz, UINT uFlags)
Definition: mmio.c:1047
MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO *lpck, UINT uFlags)
Definition: mmio.c:1238
static BOOL MMIO_Destroy(LPWINE_MMIO wm)
Definition: mmio.c:454
static struct IOProcList * MMIO_FindProcNode(FOURCC fccIOProc)
Definition: mmio.c:227
static MMRESULT MMIO_SetBuffer(WINE_MMIO *wm, void *pchBuffer, LONG cchBuffer, UINT uFlags)
Definition: mmio.c:526
LPMMIOPROC WINAPI mmioInstallIOProcA(FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags)
Definition: mmio.c:1058
static WINE_MMIO * MMIOList
Definition: mmio.c:34
FOURCC WINAPI mmioStringToFOURCCA(LPCSTR sz, UINT uFlags)
Definition: mmio.c:1024
MMRESULT WINAPI mmioRenameA(LPCSTR szFileName, LPCSTR szNewFileName, const MMIOINFO *lpmmioinfo, DWORD dwFlags)
Definition: mmio.c:1277
static LRESULT CALLBACK mmioMemIOProc(LPMMIOINFO lpmmioinfo, UINT uMessage, LPARAM lParam1, LPARAM lParam2)
Definition: mmio.c:142
LPMMIOPROC WINAPI mmioInstallIOProcW(FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags)
Definition: mmio.c:1067
static LPWINE_MMIO MMIO_Create(void)
Definition: mmio.c:431
LRESULT WINAPI mmioSendMessage(HMMIO hmmio, UINT uMessage, LPARAM lParam1, LPARAM lParam2)
Definition: mmio.c:1097
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:669
static LRESULT send_message(struct IOProcList *ioProc, LPMMIOINFO mmioinfo, DWORD wMsg, LPARAM lParam1, LPARAM lParam2, BOOL is_unicode)
Definition: mmio.c:326
MMRESULT WINAPI mmioRenameW(LPCWSTR szFileName, LPCWSTR szNewFileName, const MMIOINFO *lpmmioinfo, DWORD dwFlags)
Definition: mmio.c:1319
MMRESULT WINAPI mmioAdvance(HMMIO hmmio, MMIOINFO *lpmmioinfo, UINT uFlags)
Definition: mmio.c:975
MMRESULT WINAPI mmioSetInfo(HMMIO hmmio, const MMIOINFO *lpmmioinfo, UINT uFlags)
Definition: mmio.c:917
static LPWINE_MMIO MMIO_Get(HMMIO h)
Definition: mmio.c:413
#define assert(x)
Definition: debug.h:53
DWORD FOURCC
Definition: dmdls.h:25
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLenum GLsizei len
Definition: glext.h:6722
GLuint64EXT * result
Definition: glext.h:11304
GLintptr offset
Definition: glext.h:5920
const GLfloat * m
Definition: glext.h:10848
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
uint32_t cc
Definition: isohybrid.c:75
#define SEEK_SET
Definition: jmemansi.c:26
#define debugstr_a
Definition: kernel32.h:31
#define _lread(a, b, c)
Definition: kernel32.h:171
int WINAPI _lclose(HFILE hFile)
Definition: lfile.c:138
LONG WINAPI _llseek(HFILE hFile, LONG lOffset, int iOrigin)
Definition: lfile.c:149
long WINAPI _hwrite(HFILE hFile, LPCSTR lpBuffer, long lBytes)
Definition: lfile.c:41
#define pch(ap)
Definition: match.c:418
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define MMIO_PARSE
Definition: mmsystem.h:529
#define MMIO_FINDRIFF
Definition: mmsystem.h:552
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
#define MMIOM_RENAME
Definition: mmsystem.h:562
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define MMIOERR_CHUNKNOTFOUND
Definition: mmsystem.h:517
UINT MMRESULT
Definition: mmsystem.h:962
#define MMIO_DEFAULTBUFFER
Definition: mmsystem.h:568
#define MMIO_GETTEMP
Definition: mmsystem.h:533
#define MMIOM_WRITEFLUSH
Definition: mmsystem.h:561
#define MMIOERR_FILENOTFOUND
Definition: mmsystem.h:509
#define FOURCC_DOS
Definition: mmsystem.h:566
#define MMIO_FHOPEN
Definition: mmsystem.h:543
#define MMIOERR_OUTOFMEMORY
Definition: mmsystem.h:510
#define MMIOM_READ
Definition: mmsystem.h:556
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
#define MMIOM_USER
Definition: mmsystem.h:563
#define MMIO_CREATE
Definition: mmsystem.h:528
#define MMIO_TOUPPER
Definition: mmsystem.h:545
#define FOURCC_LIST
Definition: mmsystem.h:565
#define MMIOM_CLOSE
Definition: mmsystem.h:560
#define MMIO_CREATELIST
Definition: mmsystem.h:555
#define MMIOM_SEEK
Definition: mmsystem.h:558
#define MMIO_RWMODE
Definition: mmsystem.h:526
#define MMIO_GLOBALPROC
Definition: mmsystem.h:547
#define MMSYSERR_INVALHANDLE
Definition: mmsystem.h:101
#define MMIO_WRITE
Definition: mmsystem.h:536
#define FOURCC_MEM
Definition: mmsystem.h:567
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define MMIOM_OPEN
Definition: mmsystem.h:559
#define MMIOERR_CANNOTOPEN
Definition: mmsystem.h:511
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
MMIOPROC * LPMMIOPROC
Definition: mmsystem.h:1483
#define MMIO_REMOVEPROC
Definition: mmsystem.h:548
#define MMIO_DIRTY
Definition: mmsystem.h:534
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define MMIO_INSTALLPROC
Definition: mmsystem.h:546
#define MMIO_EMPTYBUF
Definition: mmsystem.h:544
#define MMIO_READ
Definition: mmsystem.h:535
#define MMIOM_WRITE
Definition: mmsystem.h:557
#define MMIO_CREATERIFF
Definition: mmsystem.h:554
#define MMIO_EXIST
Definition: mmsystem.h:531
#define MMIOERR_UNBUFFERED
Definition: mmsystem.h:518
#define MMIO_FINDPROC
Definition: mmsystem.h:550
#define MMIOERR_CANNOTWRITE
Definition: mmsystem.h:514
char * HPSTR
Definition: mmsystem.h:1477
#define MMIO_FINDLIST
Definition: mmsystem.h:553
#define SEEK_CUR
Definition: util.h:63
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define DWORD
Definition: nt_native.h:44
long LONG
Definition: pedump.c:60
#define errno
Definition: errno.h:18
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
#define error2(s, a, b)
Definition: debug.h:126
#define error1(s, a)
Definition: debug.h:125
#define TRACE(s)
Definition: solgame.cpp:4
BOOL is_unicode
Definition: winemm.h:138
LPMMIOPROC pIOProc
Definition: winemm.h:137
int count
Definition: winemm.h:139
struct IOProcList * pNext
Definition: winemm.h:135
FOURCC fourCC
Definition: winemm.h:136
FOURCC ckid
Definition: mmsystem.h:1507
DWORD cksize
Definition: mmsystem.h:1508
DWORD dwDataOffset
Definition: mmsystem.h:1510
DWORD dwFlags
Definition: mmsystem.h:1511
FOURCC fccType
Definition: mmsystem.h:1509
LPMMIOPROC pIOProc
Definition: mmsystem.h:1488
HPSTR pchEndRead
Definition: mmsystem.h:1494
LONG cchBuffer
Definition: mmsystem.h:1491
HPSTR pchNext
Definition: mmsystem.h:1493
DWORD dwFlags
Definition: mmsystem.h:1486
HPSTR pchEndWrite
Definition: mmsystem.h:1495
LONG lBufOffset
Definition: mmsystem.h:1496
LONG lDiskOffset
Definition: mmsystem.h:1497
HPSTR pchBuffer
Definition: mmsystem.h:1492
FOURCC fccIOProc
Definition: mmsystem.h:1487
DWORD adwInfo[3]
Definition: mmsystem.h:1498
UINT wErrorRet
Definition: mmsystem.h:1489
HMMIO hmmio
Definition: mmsystem.h:1501
DWORD dwFileSize
Definition: winemm.h:148
unsigned bBufferLoaded
Definition: winemm.h:147
struct IOProcList * ioProc
Definition: winemm.h:145
MMIOINFO info
Definition: winemm.h:143
unsigned bTmpIOProc
Definition: winemm.h:146
struct tagWINE_MMIO * lpNext
Definition: winemm.h:144
#define max(a, b)
Definition: svc.c:63
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
int ret
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define HFILE_ERROR
Definition: winbase.h:111
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
int HFILE
Definition: windef.h:298
#define WINAPI
Definition: msvc.h:6
CRITICAL_SECTION WINMM_cs
Definition: winmm.c:54
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175