1 /* 2 * Unit tests for mmio APIs 3 * 4 * Copyright 2005 Dmitry Timoshkov 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdarg.h> 22 23 #include "windef.h" 24 #include "winbase.h" 25 #include "wingdi.h" 26 #include "mmsystem.h" 27 #include "vfw.h" 28 #include "wine/test.h" 29 30 static DWORD RIFF_buf[] = 31 { 32 FOURCC_RIFF, 32*sizeof(DWORD), mmioFOURCC('A','V','I',' '), 33 FOURCC_LIST, 29*sizeof(DWORD), listtypeAVIHEADER, ckidAVIMAINHDR, 34 sizeof(MainAVIHeader), 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 35 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,0xdeadbeef, 36 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,0xdeadbeef, 37 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 38 FOURCC_LIST, 10*sizeof(DWORD),listtypeSTREAMHEADER, ckidSTREAMHEADER, 39 7*sizeof(DWORD), streamtypeVIDEO, 0xdeadbeef, 0xdeadbeef, 40 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 45 }; 46 47 static void expect_buf_offset_dbg(HMMIO hmmio, LONG off, int line) 48 { 49 MMIOINFO mmio; 50 LONG ret; 51 52 memset(&mmio, 0, sizeof(mmio)); 53 ret = mmioGetInfo(hmmio, &mmio, 0); 54 ok_(__FILE__, line)(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 55 ok_(__FILE__, line)(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 56 ret = mmioSeek(hmmio, 0, SEEK_CUR); 57 ok_(__FILE__, line)(ret == off, "expected %d, got %d\n", off, ret); 58 } 59 60 #define expect_buf_offset(a1, a2) expect_buf_offset_dbg(a1, a2, __LINE__) 61 62 static void test_mmioDescend(char *fname) 63 { 64 MMRESULT ret; 65 HMMIO hmmio; 66 MMIOINFO mmio; 67 MMCKINFO ckRiff, ckList, ck, ckList2; 68 69 memset(&mmio, 0, sizeof(mmio)); 70 mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM; 71 mmio.cchBuffer = sizeof(RIFF_buf); 72 mmio.pchBuffer = (char *)RIFF_buf; 73 hmmio = mmioOpenA(fname, &mmio, MMIO_READ); 74 if (fname && !hmmio) 75 { 76 trace("No optional %s file. Skipping the test\n", fname); 77 return; 78 } 79 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 80 81 expect_buf_offset(hmmio, 0); 82 83 /* first normal RIFF AVI parsing */ 84 ret = mmioDescend(hmmio, &ckRiff, NULL, 0); 85 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 86 ok(ckRiff.ckid == FOURCC_RIFF, "wrong ckid: %04x\n", ckRiff.ckid); 87 ok(ckRiff.fccType == formtypeAVI, "wrong fccType: %04x\n", ckRiff.fccType); 88 ok(ckRiff.dwDataOffset == 8, "expected 8 got %u\n", ckRiff.dwDataOffset); 89 trace("ckid %4.4s cksize %04x fccType %4.4s off %04x flags %04x\n", 90 (LPCSTR)&ckRiff.ckid, ckRiff.cksize, (LPCSTR)&ckRiff.fccType, 91 ckRiff.dwDataOffset, ckRiff.dwFlags); 92 93 expect_buf_offset(hmmio, 12); 94 95 ret = mmioDescend(hmmio, &ckList, &ckRiff, 0); 96 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 97 ok(ckList.ckid == FOURCC_LIST, "wrong ckid: %04x\n", ckList.ckid); 98 ok(ckList.fccType == listtypeAVIHEADER, "wrong fccType: %04x\n", ckList.fccType); 99 ok(ckList.dwDataOffset == 20, "expected 20 got %u\n", ckList.dwDataOffset); 100 trace("ckid %4.4s cksize %04x fccType %4.4s off %04x flags %04x\n", 101 (LPCSTR)&ckList.ckid, ckList.cksize, (LPCSTR)&ckList.fccType, 102 ckList.dwDataOffset, ckList.dwFlags); 103 104 expect_buf_offset(hmmio, 24); 105 106 ret = mmioDescend(hmmio, &ck, &ckList, 0); 107 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 108 ok(ck.ckid == ckidAVIMAINHDR, "wrong ckid: %04x\n", ck.ckid); 109 ok(ck.fccType == 0, "wrong fccType: %04x\n", ck.fccType); 110 trace("ckid %4.4s cksize %04x fccType %4.4s off %04x flags %04x\n", 111 (LPCSTR)&ck.ckid, ck.cksize, (LPCSTR)&ck.fccType, 112 ck.dwDataOffset, ck.dwFlags); 113 114 expect_buf_offset(hmmio, 32); 115 116 /* Skip chunk data */ 117 ret = mmioSeek(hmmio, ck.cksize, SEEK_CUR); 118 ok(ret == 0x58, "expected 0x58, got %#x\n", ret); 119 120 ret = mmioDescend(hmmio, &ckList2, &ckList, 0); 121 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 122 ok(ckList2.ckid == FOURCC_LIST, "wrong ckid: %04x\n", ckList2.ckid); 123 ok(ckList2.fccType == listtypeSTREAMHEADER, "wrong fccType: %04x\n", ckList2.fccType); 124 trace("ckid %4.4s cksize %04x fccType %4.4s off %04x flags %04x\n", 125 (LPCSTR)&ckList2.ckid, ckList2.cksize, (LPCSTR)&ckList2.fccType, 126 ckList2.dwDataOffset, ckList2.dwFlags); 127 128 expect_buf_offset(hmmio, 100); 129 130 ret = mmioDescend(hmmio, &ck, &ckList2, 0); 131 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 132 ok(ck.ckid == ckidSTREAMHEADER, "wrong ckid: %04x\n", ck.ckid); 133 ok(ck.fccType == 0, "wrong fccType: %04x\n", ck.fccType); 134 trace("ckid %4.4s cksize %04x fccType %4.4s off %04x flags %04x\n", 135 (LPCSTR)&ck.ckid, ck.cksize, (LPCSTR)&ck.fccType, 136 ck.dwDataOffset, ck.dwFlags); 137 138 expect_buf_offset(hmmio, 108); 139 140 /* test various mmioDescend flags */ 141 142 mmioSeek(hmmio, 0, SEEK_SET); 143 memset(&ck, 0x66, sizeof(ck)); 144 ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF); 145 ok(ret == MMIOERR_CHUNKNOTFOUND || 146 ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret); 147 148 mmioSeek(hmmio, 0, SEEK_SET); 149 memset(&ck, 0x66, sizeof(ck)); 150 ck.ckid = 0; 151 ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF); 152 ok(ret == MMIOERR_CHUNKNOTFOUND || 153 ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret); 154 155 mmioSeek(hmmio, 0, SEEK_SET); 156 memset(&ck, 0x66, sizeof(ck)); 157 ck.fccType = 0; 158 ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF); 159 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 160 ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04x\n", ck.ckid); 161 ok(ck.fccType == formtypeAVI, "wrong fccType: %04x\n", ck.fccType); 162 163 mmioSeek(hmmio, 0, SEEK_SET); 164 memset(&ck, 0x66, sizeof(ck)); 165 ret = mmioDescend(hmmio, &ck, NULL, 0); 166 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 167 ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04x\n", ck.ckid); 168 ok(ck.fccType == formtypeAVI, "wrong fccType: %04x\n", ck.fccType); 169 170 /* do NOT seek, use current file position */ 171 memset(&ck, 0x66, sizeof(ck)); 172 ck.fccType = 0; 173 ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDLIST); 174 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 175 ok(ck.ckid == FOURCC_LIST, "wrong ckid: %04x\n", ck.ckid); 176 ok(ck.fccType == listtypeAVIHEADER, "wrong fccType: %04x\n", ck.fccType); 177 178 mmioSeek(hmmio, 0, SEEK_SET); 179 memset(&ck, 0x66, sizeof(ck)); 180 ck.ckid = 0; 181 ck.fccType = listtypeAVIHEADER; 182 ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK); 183 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 184 ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04x\n", ck.ckid); 185 ok(ck.fccType == formtypeAVI, "wrong fccType: %04x\n", ck.fccType); 186 187 /* do NOT seek, use current file position */ 188 memset(&ck, 0x66, sizeof(ck)); 189 ck.ckid = FOURCC_LIST; 190 ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK); 191 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 192 ok(ck.ckid == FOURCC_LIST, "wrong ckid: %04x\n", ck.ckid); 193 ok(ck.fccType == listtypeAVIHEADER, "wrong fccType: %04x\n", ck.fccType); 194 195 mmioSeek(hmmio, 0, SEEK_SET); 196 memset(&ck, 0x66, sizeof(ck)); 197 ck.ckid = FOURCC_RIFF; 198 ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK); 199 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 200 ok(ck.ckid == FOURCC_RIFF, "wrong ckid: %04x\n", ck.ckid); 201 ok(ck.fccType == formtypeAVI, "wrong fccType: %04x\n", ck.fccType); 202 203 /* do NOT seek, use current file position */ 204 memset(&ckList, 0x66, sizeof(ckList)); 205 ckList.ckid = 0; 206 ret = mmioDescend(hmmio, &ckList, &ck, MMIO_FINDCHUNK); 207 ok(ret == MMSYSERR_NOERROR, "mmioDescend error %u\n", ret); 208 ok(ckList.ckid == FOURCC_LIST, "wrong ckid: %04x\n", ckList.ckid); 209 ok(ckList.fccType == listtypeAVIHEADER, "wrong fccType: %04x\n", ckList.fccType); 210 211 mmioSeek(hmmio, 0, SEEK_SET); 212 memset(&ck, 0x66, sizeof(ck)); 213 ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDCHUNK); 214 ok(ret == MMIOERR_CHUNKNOTFOUND || 215 ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret); 216 ok(ck.ckid != 0x66666666, "wrong ckid: %04x\n", ck.ckid); 217 ok(ck.fccType != 0x66666666, "wrong fccType: %04x\n", ck.fccType); 218 ok(ck.dwDataOffset != 0x66666666, "wrong dwDataOffset: %04x\n", ck.dwDataOffset); 219 220 mmioSeek(hmmio, 0, SEEK_SET); 221 memset(&ck, 0x66, sizeof(ck)); 222 ret = mmioDescend(hmmio, &ck, NULL, MMIO_FINDRIFF); 223 ok(ret == MMIOERR_CHUNKNOTFOUND || 224 ret == MMIOERR_INVALIDFILE, "mmioDescend returned %u\n", ret); 225 226 mmioClose(hmmio, 0); 227 } 228 229 static void test_mmioOpen(char *fname) 230 { 231 char buf[MMIO_DEFAULTBUFFER]; 232 MMRESULT ret; 233 HMMIO hmmio; 234 MMIOINFO mmio; 235 236 memset(&mmio, 0, sizeof(mmio)); 237 mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM; 238 mmio.cchBuffer = sizeof(buf); 239 mmio.pchBuffer = buf; 240 hmmio = mmioOpenA(fname, &mmio, MMIO_READ); 241 if (fname && !hmmio) 242 { 243 trace("No optional %s file. Skipping the test\n", fname); 244 return; 245 } 246 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 247 248 memset(&mmio, 0, sizeof(mmio)); 249 ret = mmioGetInfo(hmmio, &mmio, 0); 250 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 251 ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags); 252 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 253 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 254 ok(mmio.cchBuffer == sizeof(buf), "got %u\n", mmio.cchBuffer); 255 ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer); 256 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 257 if (mmio.fccIOProc == FOURCC_DOS) 258 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 259 else 260 ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead); 261 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 262 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 263 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 264 265 ret = mmioSeek(hmmio, 0, SEEK_CUR); 266 ok(ret == 0, "expected 0, got %d\n", ret); 267 268 mmioClose(hmmio, 0); 269 270 memset(&mmio, 0, sizeof(mmio)); 271 mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM; 272 mmio.cchBuffer = 0; 273 mmio.pchBuffer = buf; 274 hmmio = mmioOpenA(fname, &mmio, MMIO_READ); 275 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 276 277 memset(&mmio, 0, sizeof(mmio)); 278 ret = mmioGetInfo(hmmio, &mmio, 0); 279 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 280 ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags); 281 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 282 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 283 ok(mmio.cchBuffer == 0, "expected 0, got %u\n", mmio.cchBuffer); 284 ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer); 285 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 286 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 287 ok(mmio.pchEndWrite == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndWrite); 288 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 289 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 290 291 ret = mmioSeek(hmmio, 0, SEEK_CUR); 292 ok(ret == 0, "expected 0, got %d\n", ret); 293 294 mmioClose(hmmio, 0); 295 296 memset(&mmio, 0, sizeof(mmio)); 297 mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM; 298 mmio.cchBuffer = 0; 299 mmio.pchBuffer = NULL; 300 hmmio = mmioOpenA(fname, &mmio, MMIO_READ); 301 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 302 303 memset(&mmio, 0, sizeof(mmio)); 304 ret = mmioGetInfo(hmmio, &mmio, 0); 305 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 306 ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags); 307 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 308 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 309 ok(mmio.cchBuffer == 0, "expected 0, got %u\n", mmio.cchBuffer); 310 ok(mmio.pchBuffer == NULL, "expected NULL\n"); 311 ok(mmio.pchNext == NULL, "expected NULL\n"); 312 ok(mmio.pchEndRead == NULL, "expected NULL\n"); 313 ok(mmio.pchEndWrite == NULL, "expected NULL\n"); 314 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 315 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 316 317 ret = mmioSeek(hmmio, 0, SEEK_CUR); 318 ok(ret == 0, "expected 0, got %d\n", ret); 319 320 mmioClose(hmmio, 0); 321 322 memset(&mmio, 0, sizeof(mmio)); 323 mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM; 324 mmio.cchBuffer = 256; 325 mmio.pchBuffer = NULL; 326 hmmio = mmioOpenA(fname, &mmio, MMIO_READ); 327 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 328 329 memset(&mmio, 0, sizeof(mmio)); 330 ret = mmioGetInfo(hmmio, &mmio, 0); 331 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 332 ok(mmio.dwFlags == (MMIO_READ|MMIO_ALLOCBUF), "expected MMIO_READ|MMIO_ALLOCBUF, got %x\n", mmio.dwFlags); 333 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 334 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 335 ok(mmio.cchBuffer == 256, "expected 256, got %u\n", mmio.cchBuffer); 336 ok(mmio.pchBuffer != NULL, "expected not NULL\n"); 337 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 338 if (mmio.fccIOProc == FOURCC_DOS) 339 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 340 else 341 ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead); 342 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 343 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 344 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 345 346 ret = mmioSeek(hmmio, 0, SEEK_CUR); 347 ok(ret == 0, "expected 0, got %d\n", ret); 348 349 mmioClose(hmmio, 0); 350 351 memset(&mmio, 0, sizeof(mmio)); 352 mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM; 353 mmio.cchBuffer = sizeof(buf); 354 mmio.pchBuffer = buf; 355 hmmio = mmioOpenA(fname, &mmio, MMIO_READ | MMIO_ALLOCBUF); 356 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 357 358 memset(&mmio, 0, sizeof(mmio)); 359 ret = mmioGetInfo(hmmio, &mmio, 0); 360 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 361 ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags); 362 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 363 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 364 ok(mmio.cchBuffer == sizeof(buf), "got %u\n", mmio.cchBuffer); 365 ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer); 366 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 367 if (mmio.fccIOProc == FOURCC_DOS) 368 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 369 else 370 ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead); 371 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 372 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 373 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 374 375 ret = mmioSeek(hmmio, 0, SEEK_CUR); 376 ok(ret == 0, "expected 0, got %d\n", ret); 377 378 mmioClose(hmmio, 0); 379 380 memset(&mmio, 0, sizeof(mmio)); 381 mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM; 382 mmio.cchBuffer = 0; 383 mmio.pchBuffer = NULL; 384 hmmio = mmioOpenA(fname, &mmio, MMIO_READ | MMIO_ALLOCBUF); 385 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 386 387 memset(&mmio, 0, sizeof(mmio)); 388 ret = mmioGetInfo(hmmio, &mmio, 0); 389 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 390 ok(mmio.dwFlags == (MMIO_READ|MMIO_ALLOCBUF), "expected MMIO_READ|MMIO_ALLOCBUF, got %x\n", mmio.dwFlags); 391 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 392 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 393 ok(mmio.cchBuffer == MMIO_DEFAULTBUFFER, "expected MMIO_DEFAULTBUFFER, got %u\n", mmio.cchBuffer); 394 ok(mmio.pchBuffer != NULL, "expected not NULL\n"); 395 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 396 if (mmio.fccIOProc == FOURCC_DOS) 397 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 398 else 399 ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead); 400 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 401 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 402 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 403 404 ret = mmioSeek(hmmio, 0, SEEK_CUR); 405 ok(ret == 0, "expected 0, got %d\n", ret); 406 407 mmioClose(hmmio, 0); 408 409 memset(&mmio, 0, sizeof(mmio)); 410 mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM; 411 mmio.cchBuffer = 256; 412 mmio.pchBuffer = NULL; 413 hmmio = mmioOpenA(fname, &mmio, MMIO_READ | MMIO_ALLOCBUF); 414 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 415 416 memset(&mmio, 0, sizeof(mmio)); 417 ret = mmioGetInfo(hmmio, &mmio, 0); 418 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 419 ok(mmio.dwFlags == (MMIO_READ|MMIO_ALLOCBUF), "expected MMIO_READ|MMIO_ALLOCBUF, got %x\n", mmio.dwFlags); 420 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 421 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 422 ok(mmio.cchBuffer == 256, "expected 256, got %u\n", mmio.cchBuffer); 423 ok(mmio.pchBuffer != NULL, "expected not NULL\n"); 424 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 425 if (mmio.fccIOProc == FOURCC_DOS) 426 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 427 else 428 ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead); 429 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 430 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 431 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 432 433 ret = mmioSeek(hmmio, 0, SEEK_CUR); 434 ok(ret == 0, "expected 0, got %d\n", ret); 435 436 mmioClose(hmmio, 0); 437 438 memset(&mmio, 0, sizeof(mmio)); 439 mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM; 440 mmio.cchBuffer = 0; 441 mmio.pchBuffer = buf; 442 hmmio = mmioOpenA(fname, &mmio, MMIO_READ | MMIO_ALLOCBUF); 443 if (!hmmio && mmio.wErrorRet == ERROR_BAD_FORMAT) 444 { 445 /* Seen on Win9x, WinMe but also XP-SP1 */ 446 skip("Some Windows versions don't like a 0 size and a given buffer\n"); 447 return; 448 } 449 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 450 451 memset(&mmio, 0, sizeof(mmio)); 452 ret = mmioGetInfo(hmmio, &mmio, 0); 453 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 454 ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags); 455 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 456 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 457 ok(mmio.cchBuffer == MMIO_DEFAULTBUFFER, "expected MMIO_DEFAULTBUFFER, got %u\n", mmio.cchBuffer); 458 ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer); 459 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 460 if (mmio.fccIOProc == FOURCC_DOS) 461 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 462 else 463 ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead); 464 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 465 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 466 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 467 468 ret = mmioSeek(hmmio, 0, SEEK_CUR); 469 ok(ret == 0, "expected 0, got %d\n", ret); 470 471 mmioClose(hmmio, 0); 472 } 473 474 static void test_mmioSetBuffer(char *fname) 475 { 476 char buf[256]; 477 MMRESULT ret; 478 HMMIO hmmio; 479 MMIOINFO mmio; 480 481 memset(&mmio, 0, sizeof(mmio)); 482 mmio.fccIOProc = fname ? FOURCC_DOS : FOURCC_MEM; 483 mmio.cchBuffer = sizeof(buf); 484 mmio.pchBuffer = buf; 485 hmmio = mmioOpenA(fname, &mmio, MMIO_READ); 486 if (fname && !hmmio) 487 { 488 trace("No optional %s file. Skipping the test\n", fname); 489 return; 490 } 491 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 492 493 memset(&mmio, 0, sizeof(mmio)); 494 ret = mmioGetInfo(hmmio, &mmio, 0); 495 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 496 ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags); 497 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 498 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 499 ok(mmio.cchBuffer == sizeof(buf), "got %u\n", mmio.cchBuffer); 500 ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer); 501 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 502 if (mmio.fccIOProc == FOURCC_DOS) 503 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 504 else 505 ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead); 506 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 507 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 508 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 509 510 ret = mmioSeek(hmmio, 0, SEEK_CUR); 511 ok(ret == 0, "expected 0, got %d\n", ret); 512 513 ret = mmioSetBuffer(hmmio, NULL, 0, 0); 514 ok(ret == MMSYSERR_NOERROR, "mmioSetBuffer error %u\n", ret); 515 516 memset(&mmio, 0, sizeof(mmio)); 517 ret = mmioGetInfo(hmmio, &mmio, 0); 518 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 519 ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags); 520 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 521 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 522 ok(mmio.cchBuffer == 0, "got not 0\n"); 523 ok(mmio.pchBuffer == NULL, "got not NULL buf\n"); 524 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 525 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 526 ok(mmio.pchEndWrite == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndWrite); 527 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 528 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 529 530 ret = mmioSeek(hmmio, 0, SEEK_CUR); 531 ok(ret == 0, "expected 0, got %d\n", ret); 532 533 ret = mmioSetBuffer(hmmio, NULL, 0, MMIO_ALLOCBUF); 534 ok(ret == MMSYSERR_NOERROR, "mmioSetBuffer error %u\n", ret); 535 536 memset(&mmio, 0, sizeof(mmio)); 537 ret = mmioGetInfo(hmmio, &mmio, 0); 538 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 539 ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags); 540 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 541 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 542 ok(mmio.cchBuffer == 0, "got not 0\n"); 543 ok(mmio.pchBuffer == NULL, "got not NULL buf\n"); 544 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 545 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 546 ok(mmio.pchEndWrite == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndWrite); 547 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 548 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 549 550 ret = mmioSeek(hmmio, 0, SEEK_CUR); 551 ok(ret == 0, "expected 0, got %d\n", ret); 552 553 ret = mmioSetBuffer(hmmio, buf, 0, MMIO_ALLOCBUF); 554 ok(ret == MMSYSERR_NOERROR, "mmioSetBuffer error %u\n", ret); 555 556 memset(&mmio, 0, sizeof(mmio)); 557 ret = mmioGetInfo(hmmio, &mmio, 0); 558 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 559 ok(mmio.dwFlags == MMIO_READ, "expected MMIO_READ, got %x\n", mmio.dwFlags); 560 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 561 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 562 ok(mmio.cchBuffer == 0, "got not 0\n"); 563 ok(mmio.pchBuffer == buf, "expected %p, got %p\n", buf, mmio.pchBuffer); 564 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 565 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 566 ok(mmio.pchEndWrite == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndWrite); 567 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 568 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 569 570 ret = mmioSeek(hmmio, 0, SEEK_CUR); 571 ok(ret == 0, "expected 0, got %d\n", ret); 572 573 ret = mmioSetBuffer(hmmio, NULL, 256, MMIO_WRITE|MMIO_ALLOCBUF); 574 ok(ret == MMSYSERR_NOERROR, "mmioSetBuffer error %u\n", ret); 575 576 memset(&mmio, 0, sizeof(mmio)); 577 ret = mmioGetInfo(hmmio, &mmio, 0); 578 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo error %u\n", ret); 579 ok(mmio.dwFlags == (MMIO_READ|MMIO_ALLOCBUF), "expected MMIO_READ|MMIO_ALLOCBUF, got %x\n", mmio.dwFlags); 580 ok(mmio.wErrorRet == MMSYSERR_NOERROR, "expected MMSYSERR_NOERROR, got %u\n", mmio.wErrorRet); 581 ok(mmio.fccIOProc == (fname ? FOURCC_DOS : FOURCC_MEM), "got %4.4s\n", (LPCSTR)&mmio.fccIOProc); 582 ok(mmio.cchBuffer == 256, "got %u\n", mmio.cchBuffer); 583 ok(mmio.pchBuffer != NULL, "expected not NULL\n"); 584 ok(mmio.pchBuffer != buf, "expected != buf\n"); 585 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 586 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", buf, mmio.pchEndRead); 587 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 588 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 589 ok(mmio.lDiskOffset == 0, "expected 0, got %d\n", mmio.lDiskOffset); 590 591 ret = mmioSeek(hmmio, 0, SEEK_CUR); 592 ok(ret == 0, "expected 0, got %d\n", ret); 593 594 mmioClose(hmmio, 0); 595 } 596 597 #define FOURCC_XYZ mmioFOURCC('X', 'Y', 'Z', ' ') 598 599 static LRESULT CALLBACK mmio_test_IOProc(LPSTR lpMMIOInfo, UINT uMessage, LPARAM lParam1, LPARAM lParam2) 600 { 601 LPMMIOINFO lpInfo = (LPMMIOINFO) lpMMIOInfo; 602 int i; 603 604 switch (uMessage) 605 { 606 case MMIOM_OPEN: 607 if (lpInfo->fccIOProc == FOURCC_DOS) 608 lpInfo->fccIOProc = mmioFOURCC('F', 'A', 'I', 'L'); 609 for (i = 0; i < ARRAY_SIZE(lpInfo->adwInfo); i++) 610 ok(lpInfo->adwInfo[i] == 0, "[%d] Expected 0, got %u\n", i, lpInfo->adwInfo[i]); 611 return MMSYSERR_NOERROR; 612 case MMIOM_CLOSE: 613 return MMSYSERR_NOERROR; 614 case MMIOM_SEEK: 615 lpInfo->adwInfo[1]++; 616 lpInfo->lDiskOffset = 0xdeadbeef; 617 return 0; 618 default: 619 return 0; 620 } 621 } 622 623 static void test_mmioOpen_fourcc(void) 624 { 625 char fname[] = "file+name.xyz+one.two"; 626 627 LPMMIOPROC lpProc; 628 HMMIO hmmio; 629 MMIOINFO mmio; 630 631 lpProc = mmioInstallIOProcA(FOURCC_DOS, mmio_test_IOProc, MMIO_INSTALLPROC); 632 ok(lpProc == mmio_test_IOProc, "mmioInstallIOProcA error\n"); 633 634 lpProc = mmioInstallIOProcA(FOURCC_XYZ, mmio_test_IOProc, MMIO_INSTALLPROC); 635 ok(lpProc == mmio_test_IOProc, "mmioInstallIOProcA error\n"); 636 637 memset(&mmio, 0, sizeof(mmio)); 638 hmmio = mmioOpenA(fname, &mmio, MMIO_READ); 639 mmioGetInfo(hmmio, &mmio, 0); 640 ok(hmmio && mmio.fccIOProc == FOURCC_XYZ, "mmioOpenA error %u, got %4.4s\n", 641 mmio.wErrorRet, (LPCSTR)&mmio.fccIOProc); 642 ok(mmio.adwInfo[1] == 0, "mmioOpenA sent MMIOM_SEEK, got %d\n", 643 mmio.adwInfo[1]); 644 ok(mmio.lDiskOffset == 0, "mmioOpenA updated lDiskOffset, got %d\n", 645 mmio.lDiskOffset); 646 mmioClose(hmmio, 0); 647 648 /* Same test with NULL info */ 649 memset(&mmio, 0, sizeof(mmio)); 650 hmmio = mmioOpenA(fname, NULL, MMIO_READ); 651 mmioGetInfo(hmmio, &mmio, 0); 652 ok(hmmio && mmio.fccIOProc == FOURCC_XYZ, "mmioOpenA error %u, got %4.4s\n", 653 mmio.wErrorRet, (LPCSTR)&mmio.fccIOProc); 654 ok(mmio.adwInfo[1] == 0, "mmioOpenA sent MMIOM_SEEK, got %d\n", 655 mmio.adwInfo[1]); 656 ok(mmio.lDiskOffset == 0, "mmioOpenA updated lDiskOffset, got %d\n", 657 mmio.lDiskOffset); 658 mmioClose(hmmio, 0); 659 660 mmioInstallIOProcA(FOURCC_XYZ, NULL, MMIO_REMOVEPROC); 661 662 memset(&mmio, 0, sizeof(mmio)); 663 hmmio = mmioOpenA(fname, &mmio, MMIO_READ); 664 mmioGetInfo(hmmio, &mmio, 0); 665 ok(!hmmio && mmio.wErrorRet == MMIOERR_FILENOTFOUND, "mmioOpenA error %u, got %4.4s\n", 666 mmio.wErrorRet, (LPCSTR)&mmio.fccIOProc); 667 mmioClose(hmmio, 0); 668 669 mmioInstallIOProcA(FOURCC_DOS, NULL, MMIO_REMOVEPROC); 670 } 671 672 static BOOL create_test_file(char *temp_file) 673 { 674 char temp_path[MAX_PATH]; 675 DWORD ret, written; 676 HANDLE h; 677 678 ret = GetTempPathA(sizeof(temp_path), temp_path); 679 ok(ret, "Failed to get a temp path, err %d\n", GetLastError()); 680 if (!ret) 681 return FALSE; 682 683 ret = GetTempFileNameA(temp_path, "mmio", 0, temp_file); 684 ok(ret, "Failed to get a temp name, err %d\n", GetLastError()); 685 if (!ret) 686 return FALSE; 687 688 h = CreateFileA(temp_file, GENERIC_WRITE, 0, NULL, 689 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 690 ok(h != INVALID_HANDLE_VALUE, "Failed to create a file, err %d\n", GetLastError()); 691 if (h == INVALID_HANDLE_VALUE) return FALSE; 692 693 ret = WriteFile(h, RIFF_buf, sizeof(RIFF_buf), &written, NULL); 694 ok(ret, "Failed to write a file, err %d\n", GetLastError()); 695 CloseHandle(h); 696 if (!ret) DeleteFileA(temp_file); 697 return ret; 698 } 699 700 static void test_mmioSeek(void) 701 { 702 HMMIO hmmio; 703 MMIOINFO mmio; 704 LONG end, pos; 705 const LONG size = sizeof(RIFF_buf), offset = 16; 706 char test_file[MAX_PATH]; 707 MMRESULT res; 708 HFILE hfile; 709 OFSTRUCT ofs; 710 711 /* test memory file */ 712 memset(&mmio, 0, sizeof(mmio)); 713 mmio.fccIOProc = FOURCC_MEM; 714 mmio.pchBuffer = (char*)&RIFF_buf; 715 mmio.cchBuffer = sizeof(RIFF_buf); 716 hmmio = mmioOpenA(NULL, &mmio, MMIO_READ); 717 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 718 if (hmmio != NULL) { 719 /* seek to the end */ 720 end = mmioSeek(hmmio, 0, SEEK_END); 721 ok(end == size, "expected %d, got %d\n", size, end); 722 723 /* test MMIOINFO values */ 724 res = mmioGetInfo(hmmio, &mmio, 0); 725 ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res); 726 ok(mmio.pchNext == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchNext); 727 ok(mmio.pchEndRead == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndRead); 728 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 729 ok(mmio.lBufOffset == 0, "expected %d, got %d\n", 0, mmio.lBufOffset); 730 ok(mmio.lDiskOffset == 0, "expected %d, got %d\n", 0, mmio.lDiskOffset); 731 732 /* seek backward from the end */ 733 pos = mmioSeek(hmmio, offset, SEEK_END); 734 ok(pos == size-offset, "expected %d, got %d\n", size-offset, pos); 735 736 mmioClose(hmmio, 0); 737 } 738 739 if (!create_test_file(test_file)) return; 740 741 /* test standard file without buffering */ 742 hmmio = NULL; 743 memset(&mmio, 0, sizeof(mmio)); 744 mmio.fccIOProc = FOURCC_DOS; 745 mmio.pchBuffer = 0; 746 mmio.cchBuffer = 0; 747 hmmio = mmioOpenA(test_file, &mmio, MMIO_READ); 748 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 749 if (hmmio != NULL) { 750 /* seek to the end */ 751 end = mmioSeek(hmmio, 0, SEEK_END); 752 ok(end == size, "expected %d, got %d\n", size, end); 753 754 /* test MMIOINFO values */ 755 res = mmioGetInfo(hmmio, &mmio, 0); 756 ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res); 757 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 758 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 759 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 760 ok(mmio.lBufOffset == size, "expected %d, got %d\n", size, mmio.lBufOffset); 761 ok(mmio.lDiskOffset == size, "expected %d, got %d\n", size, mmio.lDiskOffset); 762 763 /* seek backward from the end */ 764 pos = mmioSeek(hmmio, offset, SEEK_END); 765 ok(pos == size-offset, "expected %d, got %d\n", size-offset, pos); 766 767 mmioClose(hmmio, 0); 768 } 769 770 /* test standard file with buffering */ 771 hmmio = NULL; 772 memset(&mmio, 0, sizeof(mmio)); 773 mmio.fccIOProc = FOURCC_DOS; 774 mmio.pchBuffer = 0; 775 mmio.cchBuffer = 0; 776 hmmio = mmioOpenA(test_file, &mmio, MMIO_READ | MMIO_ALLOCBUF); 777 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 778 if (hmmio != NULL) { 779 /* seek to the end */ 780 end = mmioSeek(hmmio, 0, SEEK_END); 781 ok(end == size, "expected %d, got %d\n", size, end); 782 783 /* test MMIOINFO values */ 784 res = mmioGetInfo(hmmio, &mmio, 0); 785 ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res); 786 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 787 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 788 ok(mmio.pchEndWrite == mmio.pchBuffer + mmio.cchBuffer, "expected %p + %d, got %p\n", mmio.pchBuffer, mmio.cchBuffer, mmio.pchEndWrite); 789 ok(mmio.lBufOffset == end, "expected %d, got %d\n", end, mmio.lBufOffset); 790 ok(mmio.lDiskOffset == size, "expected %d, got %d\n", size, mmio.lDiskOffset); 791 792 /* seek backward from the end */ 793 pos = mmioSeek(hmmio, offset, SEEK_END); 794 ok(pos == size-offset, "expected %d, got %d\n", size-offset, pos); 795 796 mmioClose(hmmio, 0); 797 } 798 799 /* test seek position inheritance from standard file handle */ 800 hfile = OpenFile(test_file, &ofs, OF_READ); 801 ok(hfile != HFILE_ERROR, "Failed to open the file, err %d\n", GetLastError()); 802 if (hfile != HFILE_ERROR) { 803 pos = _llseek(hfile, offset, SEEK_SET); 804 ok(pos != HFILE_ERROR, "Failed to seek, err %d\n", GetLastError()); 805 memset(&mmio, 0, sizeof(mmio)); 806 mmio.fccIOProc = FOURCC_DOS; 807 mmio.adwInfo[0] = (DWORD)hfile; 808 hmmio = mmioOpenA(NULL, &mmio, MMIO_READ | MMIO_DENYWRITE | MMIO_ALLOCBUF); 809 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 810 if (hmmio != NULL) { 811 pos = mmioSeek(hmmio, 0, SEEK_CUR); 812 ok(pos == offset, "expected %d, got %d\n", offset, pos); 813 mmioClose(hmmio, 0); 814 } 815 } 816 817 DeleteFileA(test_file); 818 } 819 820 static void test_mmio_end_of_file(void) 821 { 822 char test_file[MAX_PATH], buffer[128], data[16]; 823 MMIOINFO mmio; 824 HMMIO hmmio; 825 LONG ret; 826 MMRESULT res; 827 828 if (!create_test_file(test_file)) return; 829 830 memset(&mmio, 0, sizeof(mmio)); 831 mmio.fccIOProc = FOURCC_DOS; 832 mmio.pchBuffer = buffer; 833 mmio.cchBuffer = sizeof(buffer); 834 hmmio = mmioOpenA(test_file, &mmio, MMIO_READ); 835 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 836 if (hmmio == NULL) { 837 DeleteFileA(test_file); 838 return; 839 } 840 841 ret = mmioSeek(hmmio, 0, SEEK_END); 842 ok(sizeof(RIFF_buf) == ret, "got %d\n", ret); 843 844 ret = mmioRead(hmmio, data, sizeof(data)); 845 ok(ret == 0, "expected %d, got %d\n", 0, ret); 846 847 res = mmioGetInfo(hmmio, &mmio, 0); 848 ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res); 849 850 res = mmioAdvance(hmmio, &mmio, MMIO_READ); 851 ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res); 852 ok(mmio.pchNext == mmio.pchEndRead, "expected %p, got %p\n", mmio.pchEndRead, mmio.pchNext); 853 854 mmioClose(hmmio, 0); 855 DeleteFileA(test_file); 856 } 857 858 static void test_mmio_buffer_pointer(void) 859 { 860 char test_file[MAX_PATH]; 861 char buffer[5], data[16]; 862 MMIOINFO mmio; 863 HMMIO hmmio; 864 LONG size, pos; 865 MMRESULT res; 866 867 if (!create_test_file(test_file)) return; 868 869 memset(&mmio, 0, sizeof(mmio)); 870 mmio.fccIOProc = FOURCC_DOS; 871 mmio.pchBuffer = buffer; 872 mmio.cchBuffer = sizeof(buffer); 873 hmmio = mmioOpenA(test_file, &mmio, MMIO_READ); 874 ok(hmmio != 0, "mmioOpenA error %u\n", mmio.wErrorRet); 875 if (hmmio == NULL) { 876 DeleteFileA(test_file); 877 return; 878 } 879 880 /* the buffer is empty */ 881 size = mmioRead(hmmio, data, 0); 882 ok(size == 0, "expected 0, got %d\n", size); 883 res = mmioGetInfo(hmmio, &mmio, 0); 884 ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res); 885 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 886 887 /* fill the buffer */ 888 res = mmioAdvance(hmmio, &mmio, MMIO_READ); 889 ok(res == MMSYSERR_NOERROR, "mmioAdvance failed %x\n", res); 890 ok(mmio.pchEndRead-mmio.pchBuffer == sizeof(buffer), "got %d\n", (int)(mmio.pchEndRead-mmio.pchBuffer)); 891 892 /* seeking to the same buffer chunk, the buffer is kept */ 893 size = sizeof(buffer)/2; 894 pos = mmioSeek(hmmio, size, SEEK_SET); 895 ok(pos == size, "failed to seek, expected %d, got %d\n", size, pos); 896 res = mmioGetInfo(hmmio, &mmio, 0); 897 ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res); 898 ok(mmio.lBufOffset == 0, "expected 0, got %d\n", mmio.lBufOffset); 899 ok(mmio.pchNext-mmio.pchBuffer == size, "expected %d, got %d\n", size, (int)(mmio.pchNext-mmio.pchBuffer)); 900 ok(mmio.pchEndRead-mmio.pchBuffer == sizeof(buffer), "got %d\n", (int)(mmio.pchEndRead-mmio.pchBuffer)); 901 902 /* seeking to another buffer chunk, the buffer is empty */ 903 size = sizeof(buffer) * 3 + sizeof(buffer) / 2; 904 pos = mmioSeek(hmmio, size, SEEK_SET); 905 ok(pos == size, "failed to seek, got %d\n", pos); 906 res = mmioGetInfo(hmmio, &mmio, 0); 907 ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res); 908 ok(mmio.lBufOffset == size, "expected %d, got %d\n", size, mmio.lBufOffset); 909 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 910 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 911 912 /* reading a lot (as sizeof(data) > mmio.cchBuffer), the buffer is empty */ 913 size = mmioRead(hmmio, data, sizeof(data)); 914 ok(size == sizeof(data), "failed to read, got %d\n", size); 915 res = mmioGetInfo(hmmio, &mmio, 0); 916 ok(res == MMSYSERR_NOERROR, "expected 0, got %d\n", res); 917 ok(mmio.lBufOffset == pos+size, "expected %d, got %d\n", pos+size, mmio.lBufOffset); 918 ok(mmio.pchNext == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchNext); 919 ok(mmio.pchEndRead == mmio.pchBuffer, "expected %p, got %p\n", mmio.pchBuffer, mmio.pchEndRead); 920 921 mmioClose(hmmio, 0); 922 DeleteFileA(test_file); 923 } 924 925 static void test_riff_write(void) 926 { 927 static const DWORD test_write_data[] = 928 { 929 FOURCC_RIFF, 0x28, mmioFOURCC('W','A','V','E'), mmioFOURCC('d','a','t','a'), 930 0x1b, 0xdededede, 0xdededede, 0xefefefef, 931 0xefefefef, 0xbabababa, 0xbabababa, 0xefefef 932 }; 933 934 char name[] = "test_write.wav"; 935 char buf[256]; 936 MMCKINFO chunk_info[2]; 937 MMIOINFO info; 938 HMMIO mmio; 939 MMRESULT ret; 940 LONG written; 941 DWORD read; 942 HANDLE h; 943 944 memset(chunk_info, 0, sizeof(chunk_info)); 945 946 mmio = mmioOpenA(name, NULL, MMIO_ALLOCBUF|MMIO_CREATE|MMIO_READWRITE); 947 ok(mmio != NULL, "mmioOpen failed\n"); 948 949 chunk_info[0].fccType = mmioFOURCC('W','A','V','E'); 950 ret = mmioCreateChunk(mmio, chunk_info, MMIO_CREATERIFF); 951 ok(ret == MMSYSERR_NOERROR, "mmioCreateChunk failed %x\n", ret); 952 ok(chunk_info[0].ckid == FOURCC_RIFF, "chunk_info[0].ckid = %x\n", chunk_info[0].ckid); 953 ok(chunk_info[0].cksize == 0, "chunk_info[0].cksize = %d\n", chunk_info[0].cksize); 954 ok(chunk_info[0].dwDataOffset == 8, "chunk_info[0].dwDataOffset = %d\n", chunk_info[0].dwDataOffset); 955 ok(chunk_info[0].dwFlags == MMIO_DIRTY, "chunk_info[0].dwFlags = %x\n", chunk_info[0].dwFlags); 956 957 chunk_info[1].ckid = mmioFOURCC('d','a','t','a'); 958 ret = mmioCreateChunk(mmio, chunk_info+1, 0); 959 ok(ret == MMSYSERR_NOERROR, "mmioCreateChunk failed %x\n", ret); 960 ok(chunk_info[1].ckid == mmioFOURCC('d','a','t','a'), "chunk_info[1].ckid = %x\n", chunk_info[1].ckid); 961 ok(chunk_info[1].cksize == 0, "chunk_info[1].cksize = %d\n", chunk_info[1].cksize); 962 ok(chunk_info[1].dwDataOffset == 20, "chunk_info[1].dwDataOffset = %d\n", chunk_info[1].dwDataOffset); 963 ok(chunk_info[1].dwFlags == MMIO_DIRTY, "chunk_info[1].dwFlags = %x\n", chunk_info[1].dwFlags); 964 965 memset(buf, 0xde, sizeof(buf)); 966 written = mmioWrite(mmio, buf, 8); 967 ok(written == 8, "mmioWrite failed %x\n", ret); 968 969 ret = mmioGetInfo(mmio, &info, 0); 970 ok(ret == MMSYSERR_NOERROR, "mmioGetInfo failed %x\n", ret); 971 972 memset(info.pchNext, 0xef, 8); 973 info.pchNext += 8; 974 ret = mmioAdvance(mmio, &info, 1); 975 ok(ret == MMSYSERR_NOERROR, "mmioAdvance failed %x\n", ret); 976 ok(info.lBufOffset == 36, "info.lBufOffset = %d\n", info.lBufOffset); 977 978 info.dwFlags |= MMIO_DIRTY; 979 memset(info.pchNext, 0xba, 8); 980 info.pchNext += 8; 981 ret = mmioAdvance(mmio, &info, 1); 982 ok(ret == MMSYSERR_NOERROR, "mmioAdvance failed %x\n", ret); 983 ok(info.lBufOffset == 44, "info.lBufOffset = %d\n", info.lBufOffset); 984 985 info.dwFlags |= MMIO_DIRTY; 986 memset(info.pchNext, 0xef, 3); 987 info.pchNext += 3; 988 ret = mmioSetInfo(mmio, &info, 0); 989 ok(ret == MMSYSERR_NOERROR, "mmioSetInfo failed %x\n", ret); 990 991 ret = mmioAscend(mmio, chunk_info+1, 0); 992 ok(ret == MMSYSERR_NOERROR, "mmioAscend failed %x\n", ret); 993 ret = mmioAscend(mmio, chunk_info, 0); 994 ok(ret == MMSYSERR_NOERROR, "mmioAscend failed %x\n", ret); 995 ret = mmioClose(mmio, 0); 996 ok(ret == MMSYSERR_NOERROR, "mmioClose failed %x\n", ret); 997 998 h = CreateFileA("test_write.wav", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); 999 ok(h != INVALID_HANDLE_VALUE, "CreateFile failed\n"); 1000 ok(ReadFile(h, buf, sizeof(buf), &read, NULL), "ReadFile failed\n"); 1001 CloseHandle(h); 1002 ok(!memcmp(buf, test_write_data, sizeof(test_write_data)), "created file is incorrect\n"); 1003 1004 DeleteFileA("test_write.wav"); 1005 } 1006 1007 START_TEST(mmio) 1008 { 1009 /* Make it possible to run the tests against a specific AVI file in 1010 * addition to the builtin test data. This is mostly meant as a 1011 * debugging aid and is not part of the standard tests. 1012 */ 1013 char fname[] = "msrle.avi"; 1014 1015 test_mmioDescend(NULL); 1016 test_mmioDescend(fname); 1017 test_mmioOpen(NULL); 1018 test_mmioOpen(fname); 1019 test_mmioSetBuffer(NULL); 1020 test_mmioSetBuffer(fname); 1021 test_mmioOpen_fourcc(); 1022 test_mmioSeek(); 1023 test_mmio_end_of_file(); 1024 test_mmio_buffer_pointer(); 1025 test_riff_write(); 1026 } 1027