ReactOS  0.4.14-dev-114-gc8cbd56
api.c
Go to the documentation of this file.
1 /*
2  * Unit test suite for AVI Functions
3  *
4  * Copyright 2008 Detlef Riekenberg
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 
22 #define COBJMACROS
23 #define CONST_VTABLE
24 
25 #include "wine/test.h"
26 #include "initguid.h"
27 #include "wingdi.h"
28 #include "vfw.h"
29 
30 /* ########################### */
31 
32 DEFINE_AVIGUID(CLSID_WAVFile, 0x00020003, 0, 0);
33 static const CHAR winetest0[] = "winetest0";
34 static const CHAR winetest1[] = "winetest1";
35 static const CHAR testfilename[] = "wine_avifil32_test.avi";
36 
37 /* ########################### */
38 
39 static const DWORD deffh[] = /* file_header */
40 {
41  FOURCC_RIFF, 0x34c6 /* length */, formtypeAVI,
42  FOURCC_LIST, 0x1ac /* length */,
44 };
45 
46 static const MainAVIHeader defmah =
47 {
48  0x00008256, /* dwMicroSecPerFrame */
49  0x000080e8, /* dwMaxBytesPerSec */
50  0x00000000, /* dwPaddingGranularity */
51  0x00000910, /* dwFlags */
52  1, /* dwTotalFrames */
53  0, /* dwInitialFrames */
54  2, /* dwStreams */
55  0x00100000, /* dwSuggestedBufferSize*/
56  8, /* dwWidth */
57  6, /* dwHeight */
58  { 0, 0, 0, 0 } /* dwReserved[4] */
59 };
60 
61 static const AVIStreamHeader defash0 =
62 {
63  streamtypeVIDEO, /* fccType */
64  0x30323449, /* fccHandler */
65  0x00000000, /* dwFlags */
66  0, /* wPriority */
67  0, /* wLanguage */
68  0, /* dwInitialFrames */
69  0x000003e9, /* dwScale */
70  0x00007530, /* dwRate */
71  0, /* dwStart */
72  1, /* dwLength */
73  0x00100000, /* dwSuggestedBufferSize*/
74  0xffffffff, /* dwQuality */
75  0, /* dwSampleSize */
76  { 0, 0, 0, 0 } /* short left right top bottom */
77 };
78 
79 static const AVIStreamHeader defash1 =
80 {
81  /* AVIStreamHeader */
82  streamtypeAUDIO, /* fccType */
83  1, /* fccHandler */
84  0, /* dwFlags */
85  0, /* wPriority */
86  0, /* wLanguage */
87  0, /* dwInitialFrames */
88  1, /* dwScale */
89  0x00002b11, /* dwRate */
90  0, /* dwStart */
91  0x00000665, /* dwLength */
92  0x00003000, /* dwSuggestedBufferSize*/
93  0xffffffff, /* dwQuality */
94  2, /* dwSampleSize */
95  { 0, 0, 0, 0 } /* short left right top bottom */
96 };
97 
98 static const PCMWAVEFORMAT defpcmwf =
99 {
100  {
101  1, /* wFormatTag */
102  2, /* nChannels */
103  11025, /* nSamplesPerSec */
104  22050, /* nAvgBytesPerSec */
105  2, /* nBlockAlign */
106  },
107  8, /* wBitsPerSample */
108 };
109 
110 typedef struct common_avi_headers {
111  DWORD fh[sizeof(deffh)];
117 
118 /* Extra data needed to get the VFW API to load the file */
119 /* DWORD deffh */
120 /* MainAVIHeader mah */
121 static const DWORD streamlist[] =
122 {
123  FOURCC_LIST, 0xd4 /* length */,
124  listtypeSTREAMHEADER, ckidSTREAMHEADER, 0x38 /* length */,
125 };
126 /* AVIStreamHeader ash0 */
127 static const DWORD videostreamformat[] =
128 {
129  ckidSTREAMFORMAT, 0x28 /* length */,
130  0x00000028, 0x00000008, 0x00000006, 0x00180001,
131  0x30323449, 0x00000090, 0x00000000, 0x00000000,
132  0x00000000, 0x00000000,
133 };
134 static const DWORD padding1[] =
135 {
136  ckidAVIPADDING, 0xc /* length */,
137  0x00000004, 0x00000000, 0x63643030
138 };
139 static const DWORD videopropheader[] =
140 {
141  0x70727076, 0x44 /* length */,
142  0x00000000, 0x00000000,
143  0x0000001e, 0x00000008, 0x00000006, 0x00100009,
144  0x00000008, 0x00000006, 0x00000001, 0x00000006,
145  0x00000008, 0x00000006, 0x00000008, 0x00000000,
146  0x00000000, 0x00000000, 0x00000000,
147  FOURCC_LIST, 0x70 /* length */,
148  listtypeSTREAMHEADER, ckidSTREAMHEADER, 0x38 /* length */,
149 };
150 /* AVIStreamHeader ash1 */
151 static const DWORD audiostreamformat_pre[] =
152 {
153  ckidSTREAMFORMAT, sizeof(PCMWAVEFORMAT) /* length */,
154 };
155 /* PCMWAVEFORMAT pcmwf */
156 static DWORD data[] =
157 {
158  ckidAVIPADDING, 0xc /* length */,
159  0x00000004, 0x00000000, 0x62773130,
160  ckidAVIPADDING, 0xc /* length */,
161  0x6c6d646f, 0x686c6d64, 0x000000f8,
162  FOURCC_LIST, 0x18 /* length */,
163  0x4f464e49,
164  0x54465349, 0xc /* length */,
165  0x6676614c, 0x332e3235, 0x00302e37,
166  ckidAVIPADDING, 0x4 /* length */,
167  0,
168  FOURCC_LIST, 0xd1b /* length */, listtypeAVIMOVIE,
169  0, 0
170 };
171 
172 /* ########################### */
173 
174 static void test_AVISaveOptions(void)
175 {
177  LPAVICOMPRESSOPTIONS poptions[2];
178  PAVISTREAM streams[2] = {NULL, NULL};
179  HRESULT hres;
180  DWORD res;
181  LONG lres;
182 
183  poptions[0] = &options[0];
184  poptions[1] = &options[1];
185  ZeroMemory(options, sizeof(options));
186 
187  SetLastError(0xdeadbeef);
188  hres = CreateEditableStream(&streams[0], NULL);
189  ok(hres == AVIERR_OK, "0: got 0x%x and %p (expected AVIERR_OK)\n", hres, streams[0]);
190 
191  SetLastError(0xdeadbeef);
192  hres = CreateEditableStream(&streams[1], NULL);
193  ok(hres == AVIERR_OK, "1: got 0x%x and %p (expected AVIERR_OK)\n", hres, streams[1]);
194 
195  SetLastError(0xdeadbeef);
196  hres = EditStreamSetNameA(streams[0], winetest0);
197  ok(hres == AVIERR_OK, "0: got 0x%x (expected AVIERR_OK)\n", hres);
198 
199  SetLastError(0xdeadbeef);
200  hres = EditStreamSetNameA(streams[1], winetest1);
201  ok(hres == AVIERR_OK, "1: got 0x%x (expected AVIERR_OK)\n", hres);
202 
203  if (winetest_interactive) {
204  SetLastError(0xdeadbeef);
206  2, streams, poptions);
207  trace("got %u with 0x%x/%u\n", res, GetLastError(), GetLastError());
208  }
209 
210  SetLastError(0xdeadbeef);
211  lres = AVISaveOptionsFree(2, poptions);
212  ok(lres == AVIERR_OK, "got 0x%x with 0x%x/%u\n", lres, GetLastError(), GetLastError());
213 
214  SetLastError(0xdeadbeef);
215  res = AVIStreamRelease(streams[0]);
216  ok(res == 0, "0: got refcount %u (expected 0)\n", res);
217 
218  SetLastError(0xdeadbeef);
219  res = AVIStreamRelease(streams[1]);
220  ok(res == 0, "1: got refcount %u (expected 0)\n", res);
221 
222 }
223 
224 /* ########################### */
225 
226 static void test_EditStreamSetInfo(void)
227 {
229  HRESULT hres;
230  AVISTREAMINFOA info, info2;
231 
233  ok(hres == AVIERR_OK, "got 0x%08X, expected AVIERR_OK\n", hres);
234 
235  /* Size parameter is somehow checked (notice the crash with size=-1 below) */
237  ok( hres == AVIERR_BADSIZE, "got 0x%08X, expected AVIERR_BADSIZE\n", hres);
238 
240  ok( hres == AVIERR_BADSIZE, "got 0x%08X, expected AVIERR_BADSIZE\n", hres);
241 
242  if(0)
243  {
244  /* Crashing - first parameter not checked */
245  EditStreamSetInfoA(NULL, &info, sizeof(info) );
246 
247  /* Crashing - second parameter not checked */
249 
251  }
252 
253  hres = AVIStreamInfoA(stream, &info, sizeof(info) );
254  ok( hres == 0, "got 0x%08X, expected 0\n", hres);
255 
256  /* Does the function check what's it's updating ? */
257 
258 #define IS_INFO_UPDATED(m) do { \
259  hres = EditStreamSetInfoA(stream, &info, sizeof(info) ); \
260  ok( hres == 0, "got 0x%08X, expected 0\n", hres); \
261  hres = AVIStreamInfoA(stream, &info2, sizeof(info2) ); \
262  ok( hres == 0, "got 0x%08X, expected 0\n", hres); \
263  ok( info2.m == info.m, "EditStreamSetInfo did not update "#m" parameter\n" ); \
264  } while(0)
265 
266  info.dwStart++;
267  IS_INFO_UPDATED(dwStart);
268  info.dwStart = 0;
269  IS_INFO_UPDATED(dwStart);
270 
271  info.wPriority++;
272  IS_INFO_UPDATED(wPriority);
273  info.wPriority = 0;
274  IS_INFO_UPDATED(wPriority);
275 
276  info.wLanguage++;
277  IS_INFO_UPDATED(wLanguage);
278  info.wLanguage = 0;
279  IS_INFO_UPDATED(wLanguage);
280 
281  info.dwScale++;
282  IS_INFO_UPDATED(dwScale);
283  info.dwScale = 0;
284  IS_INFO_UPDATED(dwScale);
285 
286  info.dwRate++;
287  IS_INFO_UPDATED(dwRate);
288  info.dwRate = 0;
289  IS_INFO_UPDATED(dwRate);
290 
291  info.dwQuality++;
292  IS_INFO_UPDATED(dwQuality);
293  info.dwQuality = 0;
294  IS_INFO_UPDATED(dwQuality);
295  info.dwQuality = -2;
296  IS_INFO_UPDATED(dwQuality);
297  info.dwQuality = ICQUALITY_HIGH+1;
298  IS_INFO_UPDATED(dwQuality);
299 
300  info.rcFrame.left = 0;
301  IS_INFO_UPDATED(rcFrame.left);
302  info.rcFrame.top = 0;
303  IS_INFO_UPDATED(rcFrame.top);
304  info.rcFrame.right = 0;
305  IS_INFO_UPDATED(rcFrame.right);
306  info.rcFrame.bottom = 0;
307  IS_INFO_UPDATED(rcFrame.bottom);
308 
309  info.rcFrame.left = -1;
310  IS_INFO_UPDATED(rcFrame.left);
311  info.rcFrame.top = -1;
312  IS_INFO_UPDATED(rcFrame.top);
313  info.rcFrame.right = -1;
314  IS_INFO_UPDATED(rcFrame.right);
315  info.rcFrame.bottom = -1;
316  IS_INFO_UPDATED(rcFrame.bottom);
318 #undef IS_INFO_UPDATED
319 }
320 
321 
323 {
324  memcpy(cah->fh, deffh, sizeof(deffh));
325  cah->mah = defmah;
326  cah->ash0 = defash0;
327  cah->ash1 = defash1;
328  cah->pcmwf = defpcmwf;
329 }
330 
331 static void create_avi_file(const COMMON_AVI_HEADERS *cah, char *filename)
332 {
333  HANDLE hFile;
334  DWORD written;
335 
337 
338  ok(hFile != INVALID_HANDLE_VALUE, "Couldn't create file\n");
339 
340  WriteFile(hFile, &cah->fh, sizeof(deffh), &written, NULL);
341  WriteFile(hFile, &cah->mah, sizeof(MainAVIHeader), &written, NULL);
342  WriteFile(hFile, streamlist, sizeof(streamlist), &written, NULL);
343  WriteFile(hFile, &cah->ash0, 0x38, &written, NULL);
345  WriteFile(hFile, padding1, sizeof(padding1), &written, NULL);
346  WriteFile(hFile, videopropheader, sizeof(videopropheader), &written, NULL);
347  WriteFile(hFile, &cah->ash1, 0x38, &written, NULL);
349  WriteFile(hFile, &cah->pcmwf, sizeof(PCMWAVEFORMAT), &written, NULL);
350  WriteFile(hFile, data, sizeof(data), &written, NULL);
351 
353 }
354 
355 static void test_default_data(void)
356 {
357  COMMON_AVI_HEADERS cah;
358  char filename[MAX_PATH];
359  PAVIFILE pFile;
360  int res;
361  LONG lSize;
362  PAVISTREAM pStream0;
363  PAVISTREAM pStream1;
364  AVISTREAMINFOA asi0, asi1;
365  WAVEFORMATEX wfx;
366 
369 
370  init_test_struct(&cah);
371  create_avi_file(&cah, filename);
372 
374  ok(res == 0, "Unable to open file: error=%u\n", res);
375 
376  pStream0 = (void *)0xdeadbeef;
377  res = AVIFileGetStream(pFile, &pStream0, ~0U, 0);
378  ok(res == AVIERR_NODATA, "expected AVIERR_NODATA, got %u\n", res);
379  ok(pStream0 == NULL, "AVIFileGetStream should set stream to NULL\n");
380 
381  res = AVIFileGetStream(pFile, &pStream0, 0, 0);
382  ok(res == 0, "Unable to open video stream: error=%u\n", res);
383 
384  res = AVIFileGetStream(pFile, &pStream1, 0, 1);
385  ok(res == 0, "Unable to open audio stream: error=%u\n", res);
386 
387  res = AVIStreamInfoA(pStream0, &asi0, sizeof(asi0));
388  ok(res == 0, "Unable to read stream info: error=%u\n", res);
389 
390  res = AVIStreamInfoA(pStream1, &asi1, sizeof(asi1));
391  ok(res == 0, "Unable to read stream info: error=%u\n", res);
392 
393  res = AVIStreamReadFormat(pStream0, AVIStreamStart(pStream1), NULL, &lSize);
394  ok(res == 0, "Unable to read format size: error=%u\n", res);
395 
396  res = AVIStreamReadFormat(pStream1, AVIStreamStart(pStream1), &wfx, &lSize);
397  ok(res == 0, "Unable to read format: error=%u\n", res);
398 
399  ok(asi0.fccType == streamtypeVIDEO, "got 0x%x (expected streamtypeVIDEO)\n", asi0.fccType);
400  ok(asi0.fccHandler == 0x30323449, "got 0x%x (expected 0x30323449)\n", asi0.fccHandler);
401  ok(asi0.dwFlags == 0, "got %u (expected 0)\n", asi0.dwFlags);
402  ok(asi0.wPriority == 0, "got %u (expected 0)\n", asi0.wPriority);
403  ok(asi0.wLanguage == 0, "got %u (expected 0)\n", asi0.wLanguage);
404  ok(asi0.dwScale == 1001, "got %u (expected 1001)\n", asi0.dwScale);
405  ok(asi0.dwRate == 30000, "got %u (expected 30000)\n", asi0.dwRate);
406  ok(asi0.dwStart == 0, "got %u (expected 0)\n", asi0.dwStart);
407  ok(asi0.dwLength == 1, "got %u (expected 1)\n", asi0.dwLength);
408  ok(asi0.dwInitialFrames == 0, "got %u (expected 0)\n", asi0.dwInitialFrames);
409  ok(asi0.dwSuggestedBufferSize == 0, "got %u (expected 0)\n", asi0.dwSuggestedBufferSize);
410  ok(asi0.dwQuality == 0xffffffff, "got 0x%x (expected 0xffffffff)\n", asi0.dwQuality);
411  ok(asi0.dwSampleSize == 0, "got %u (expected 0)\n", asi0.dwSampleSize);
412  ok(asi0.rcFrame.left == 0, "got %u (expected 0)\n", asi0.rcFrame.left);
413  ok(asi0.rcFrame.top == 0, "got %u (expected 0)\n", asi0.rcFrame.top);
414  ok(asi0.rcFrame.right == 8, "got %u (expected 8)\n", asi0.rcFrame.right); /* these are based on the values in the mah and not */
415  ok(asi0.rcFrame.bottom == 6, "got %u (expected 6)\n", asi0.rcFrame.bottom);/* on the ones in the ash which are 0 here */
416  ok(asi0.dwEditCount == 0, "got %u (expected 0)\n", asi0.dwEditCount);
417  ok(asi0.dwFormatChangeCount == 0, "got %u (expected 0)\n", asi0.dwFormatChangeCount);
418 
419  ok(asi1.fccType == streamtypeAUDIO, "got 0x%x (expected streamtypeVIDEO)\n", asi1.fccType);
420  ok(asi1.fccHandler == 0x1, "got 0x%x (expected 0x1)\n", asi1.fccHandler);
421  ok(asi1.dwFlags == 0, "got %u (expected 0)\n", asi1.dwFlags);
422  ok(asi1.wPriority == 0, "got %u (expected 0)\n", asi1.wPriority);
423  ok(asi1.wLanguage == 0, "got %u (expected 0)\n", asi1.wLanguage);
424  ok(asi1.dwScale == 1, "got %u (expected 1)\n", asi1.dwScale);
425  ok(asi1.dwRate == 11025, "got %u (expected 11025)\n", asi1.dwRate);
426  ok(asi1.dwStart == 0, "got %u (expected 0)\n", asi1.dwStart);
427  ok(asi1.dwLength == 1637, "got %u (expected 1637)\n", asi1.dwLength);
428  ok(asi1.dwInitialFrames == 0, "got %u (expected 0)\n", asi1.dwInitialFrames);
429  ok(asi1.dwSuggestedBufferSize == 0, "got %u (expected 0)\n", asi1.dwSuggestedBufferSize);
430  ok(asi1.dwQuality == 0xffffffff, "got 0x%x (expected 0xffffffff)\n", asi1.dwQuality);
431  ok(asi1.dwSampleSize == 2, "got %u (expected 2)\n", asi1.dwSampleSize);
432  ok(asi1.rcFrame.left == 0, "got %u (expected 0)\n", asi1.rcFrame.left);
433  ok(asi1.rcFrame.top == 0, "got %u (expected 0)\n", asi1.rcFrame.top);
434  ok(asi1.rcFrame.right == 0, "got %u (expected 0)\n", asi1.rcFrame.right);
435  ok(asi1.rcFrame.bottom == 0, "got %u (expected 0)\n", asi1.rcFrame.bottom);
436  ok(asi1.dwEditCount == 0, "got %u (expected 0)\n", asi1.dwEditCount);
437  ok(asi1.dwFormatChangeCount == 0, "got %u (expected 0)\n", asi1.dwFormatChangeCount);
438 
439  ok(wfx.wFormatTag == 1, "got %u (expected 1)\n",wfx.wFormatTag);
440  ok(wfx.nChannels == 2, "got %u (expected 2)\n",wfx.nChannels);
441  ok(wfx.wFormatTag == 1, "got %u (expected 1)\n",wfx.wFormatTag);
442  ok(wfx.nSamplesPerSec == 11025, "got %u (expected 11025)\n",wfx.nSamplesPerSec);
443  ok(wfx.nAvgBytesPerSec == 22050, "got %u (expected 22050)\n",wfx.nAvgBytesPerSec);
444  ok(wfx.nBlockAlign == 2, "got %u (expected 2)\n",wfx.nBlockAlign);
445 
446  AVIStreamRelease(pStream0);
447  AVIStreamRelease(pStream1);
448  AVIFileRelease(pFile);
449  ok(DeleteFileA(filename) !=0, "Deleting file %s failed\n", filename);
450 }
451 
452 static void test_amh_corruption(void)
453 {
454  COMMON_AVI_HEADERS cah;
455  char filename[MAX_PATH];
456  PAVIFILE pFile;
457  int res;
458 
461 
462  /* Make sure only AVI files with the proper headers will be loaded */
463  init_test_struct(&cah);
464  cah.fh[3] = mmioFOURCC('A', 'V', 'i', ' ');
465 
466  create_avi_file(&cah, filename);
468  ok(res != 0, "Able to open file: error=%u\n", res);
469 
470  ok(DeleteFileA(filename) !=0, "Deleting file %s failed\n", filename);
471 }
472 
473 static void test_ash1_corruption(void)
474 {
475  COMMON_AVI_HEADERS cah;
476  char filename[MAX_PATH];
477  PAVIFILE pFile;
478  int res;
479  PAVISTREAM pStream1;
480  AVISTREAMINFOA asi1;
481 
484 
485  /* Corrupt the sample size in the audio stream header */
486  init_test_struct(&cah);
487  cah.ash1.dwSampleSize = 0xdeadbeef;
488 
489  create_avi_file(&cah, filename);
490 
492  ok(res == 0, "Unable to open file: error=%u\n", res);
493 
494  res = AVIFileGetStream(pFile, &pStream1, 0, 1);
495  ok(res == 0, "Unable to open audio stream: error=%u\n", res);
496 
497  res = AVIStreamInfoA(pStream1, &asi1, sizeof(asi1));
498  ok(res == 0, "Unable to read stream info: error=%u\n", res);
499 
500  /* The result will still be 2, because the value is dynamically replaced with the nBlockAlign
501  value from the stream format header. The next test will prove this */
502  ok(asi1.dwSampleSize == 2, "got %u (expected 2)\n", asi1.dwSampleSize);
503 
504  AVIStreamRelease(pStream1);
505  AVIFileRelease(pFile);
506  ok(DeleteFileA(filename) !=0, "Deleting file %s failed\n", filename);
507 }
508 
509 static void test_ash1_corruption2(void)
510 {
511  COMMON_AVI_HEADERS cah;
512  char filename[MAX_PATH];
513  PAVIFILE pFile;
514  int res;
515  PAVISTREAM pStream1;
516  AVISTREAMINFOA asi1;
517 
520 
521  /* Corrupt the block alignment in the audio format header */
522  init_test_struct(&cah);
523  cah.pcmwf.wf.nBlockAlign = 0xdead;
524 
525  create_avi_file(&cah, filename);
526 
528  ok(res == 0, "Unable to open file: error=%u\n", res);
529 
530  res = AVIFileGetStream(pFile, &pStream1, 0, 1);
531  ok(res == 0, "Unable to open audio stream: error=%u\n", res);
532 
533  ok(AVIStreamInfoA(pStream1, &asi1, sizeof(asi1)) == 0, "Unable to read stream info\n");
534 
535  /* The result will also be the corrupt value, as explained above. */
536  ok(asi1.dwSampleSize == 0xdead, "got 0x%x (expected 0xdead)\n", asi1.dwSampleSize);
537 
538  AVIStreamRelease(pStream1);
539  AVIFileRelease(pFile);
540  ok(DeleteFileA(filename) !=0, "Deleting file %s failed\n", filename);
541 }
542 
543 /* Outer IUnknown for COM aggregation tests */
544 struct unk_impl {
548 };
549 
550 static inline struct unk_impl *impl_from_IUnknown(IUnknown *iface)
551 {
552  return CONTAINING_RECORD(iface, struct unk_impl, IUnknown_iface);
553 }
554 
556 {
557  struct unk_impl *This = impl_from_IUnknown(iface);
558  LONG ref = This->ref;
559  HRESULT hr;
560 
562  {
563  *ppv = iface;
564  IUnknown_AddRef(iface);
565  return S_OK;
566  }
567 
568  hr = IUnknown_QueryInterface(This->inner_unk, riid, ppv);
569  if (hr == S_OK)
570  {
571  trace("Working around COM aggregation ref counting bug\n");
572  ok(ref == This->ref, "Outer ref count expected %d got %d\n", ref, This->ref);
573  IUnknown_AddRef((IUnknown*)*ppv);
574  ref = IUnknown_Release(This->inner_unk);
575  ok(ref == 1, "Inner ref count expected 1 got %d\n", ref);
576  }
577 
578  return hr;
579 }
580 
582 {
583  struct unk_impl *This = impl_from_IUnknown(iface);
584 
585  return InterlockedIncrement(&This->ref);
586 }
587 
589 {
590  struct unk_impl *This = impl_from_IUnknown(iface);
591 
592  return InterlockedDecrement(&This->ref);
593 }
594 
595 static const IUnknownVtbl unk_vtbl =
596 {
598  unk_AddRef,
600 };
601 
602 static void test_COM(void)
603 {
604  struct unk_impl unk_obj = {{&unk_vtbl}, 19, NULL};
605  IAVIFile *avif = NULL;
606  IPersistFile *pf;
607  IUnknown *unk;
608  LONG refcount;
609  HRESULT hr;
610 
611  /* COM aggregation */
612  hr = CoCreateInstance(&CLSID_AVIFile, &unk_obj.IUnknown_iface, CLSCTX_INPROC_SERVER,
613  &IID_IUnknown, (void**)&unk_obj.inner_unk);
614  ok(hr == S_OK, "COM aggregation failed: %08x, expected S_OK\n", hr);
615  hr = IUnknown_QueryInterface(&unk_obj.IUnknown_iface, &IID_IAVIFile, (void**)&avif);
616  ok(hr == S_OK, "QueryInterface for IID_IAVIFile failed: %08x\n", hr);
617  refcount = IAVIFile_AddRef(avif);
618  ok(refcount == unk_obj.ref, "AVIFile just pretends to support COM aggregation\n");
619  refcount = IAVIFile_Release(avif);
620  ok(refcount == unk_obj.ref, "AVIFile just pretends to support COM aggregation\n");
621  hr = IAVIFile_QueryInterface(avif, &IID_IPersistFile, (void**)&pf);
622  ok(hr == S_OK, "QueryInterface for IID_IPersistFile failed: %08x\n", hr);
623  refcount = IPersistFile_Release(pf);
624  ok(refcount == unk_obj.ref, "AVIFile just pretends to support COM aggregation\n");
625  refcount = IAVIFile_Release(avif);
626  ok(refcount == 19, "Outer ref count should be back at 19 but is %d\n", refcount);
627  refcount = IUnknown_Release(unk_obj.inner_unk);
628  ok(refcount == 0, "Inner ref count should be 0 but is %u\n", refcount);
629 
630  /* Invalid RIID */
631  hr = CoCreateInstance(&CLSID_AVIFile, NULL, CLSCTX_INPROC_SERVER, &IID_IAVIStream,
632  (void**)&avif);
633  ok(hr == E_NOINTERFACE, "AVIFile create failed: %08x, expected E_NOINTERFACE\n", hr);
634 
635  /* Same refcount */
636  hr = CoCreateInstance(&CLSID_AVIFile, NULL, CLSCTX_INPROC_SERVER, &IID_IAVIFile, (void**)&avif);
637  ok(hr == S_OK, "AVIFile create failed: %08x, expected S_OK\n", hr);
638  refcount = IAVIFile_AddRef(avif);
639  ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
640  hr = IAVIFile_QueryInterface(avif, &IID_IUnknown, (void**)&unk);
641  ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr);
642  refcount = IUnknown_AddRef(unk);
643  ok(refcount == 4, "refcount == %u, expected 4\n", refcount);
644  hr = IAVIFile_QueryInterface(avif, &IID_IPersistFile, (void**)&pf);
645  ok(hr == S_OK, "QueryInterface for IID_IPersistFile failed: %08x\n", hr);
646  refcount = IPersistFile_AddRef(pf);
647  ok(refcount == 6, "refcount == %u, expected 6\n", refcount);
648 
649  while (IAVIFile_Release(avif));
650 }
651 
652 static void test_COM_wavfile(void)
653 {
654  struct unk_impl unk_obj = {{&unk_vtbl}, 19, NULL};
655  IAVIFile *avif = NULL;
656  IPersistFile *pf;
657  IAVIStream *avis;
658  IUnknown *unk;
659  ULONG refcount;
660  HRESULT hr;
661 
662  /* COM aggregation */
663  hr = CoCreateInstance(&CLSID_WAVFile, &unk_obj.IUnknown_iface, CLSCTX_INPROC_SERVER,
664  &IID_IUnknown, (void**)&unk_obj.inner_unk);
665  ok(hr == S_OK, "COM aggregation failed: %08x, expected S_OK\n", hr);
666  hr = IUnknown_QueryInterface(&unk_obj.IUnknown_iface, &IID_IAVIFile, (void**)&avif);
667  ok(hr == S_OK, "QueryInterface for IID_IAVIFile failed: %08x\n", hr);
668  refcount = IAVIFile_AddRef(avif);
669  ok(refcount == unk_obj.ref, "WAVFile just pretends to support COM aggregation\n");
670  refcount = IAVIFile_Release(avif);
671  ok(refcount == unk_obj.ref, "WAVFile just pretends to support COM aggregation\n");
672  hr = IAVIFile_QueryInterface(avif, &IID_IPersistFile, (void**)&pf);
673  ok(hr == S_OK, "QueryInterface for IID_IPersistFile failed: %08x\n", hr);
674  refcount = IPersistFile_Release(pf);
675  ok(refcount == unk_obj.ref, "WAVFile just pretends to support COM aggregation\n");
676  refcount = IAVIFile_Release(avif);
677  ok(refcount == 19, "Outer ref count should be back at 19 but is %d\n", refcount);
678  refcount = IUnknown_Release(unk_obj.inner_unk);
679  ok(refcount == 0, "Inner ref count should be 0 but is %u\n", refcount);
680 
681  /* Invalid RIID */
682  hr = CoCreateInstance(&CLSID_WAVFile, NULL, CLSCTX_INPROC_SERVER, &IID_IAVIStreaming,
683  (void**)&avif);
684  ok(hr == E_NOINTERFACE, "WAVFile create failed: %08x, expected E_NOINTERFACE\n", hr);
685 
686  /* Same refcount for all WAVFile interfaces */
687  hr = CoCreateInstance(&CLSID_WAVFile, NULL, CLSCTX_INPROC_SERVER, &IID_IAVIFile, (void**)&avif);
688  ok(hr == S_OK, "WAVFile create failed: %08x, expected S_OK\n", hr);
689  refcount = IAVIFile_AddRef(avif);
690  ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
691 
692  hr = IAVIFile_QueryInterface(avif, &IID_IPersistFile, (void**)&pf);
693  ok(hr == S_OK, "QueryInterface for IID_IPersistFile failed: %08x\n", hr);
694  refcount = IPersistFile_AddRef(pf);
695  ok(refcount == 4, "refcount == %u, expected 4\n", refcount);
696  refcount = IPersistFile_Release(pf);
697 
698  hr = IAVIFile_QueryInterface(avif, &IID_IAVIStream, (void**)&avis);
699  ok(hr == S_OK, "QueryInterface for IID_IAVIStream failed: %08x\n", hr);
700  refcount = IAVIStream_AddRef(avis);
701  ok(refcount == 5, "refcount == %u, expected 5\n", refcount);
702  refcount = IAVIStream_Release(avis);
703 
704  hr = IAVIFile_QueryInterface(avif, &IID_IUnknown, (void**)&unk);
705  ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr);
706  refcount = IUnknown_AddRef(unk);
707  ok(refcount == 6, "refcount == %u, expected 6\n", refcount);
708  refcount = IUnknown_Release(unk);
709 
710  while (IAVIFile_Release(avif));
711 }
712 
713 static void test_COM_editstream(void)
714 {
715  IAVIEditStream *edit;
717  IUnknown *unk;
718  ULONG refcount;
719  HRESULT hr;
720 
721  /* Same refcount for all AVIEditStream interfaces */
723  ok(hr == S_OK, "AVIEditStream create failed: %08x, expected S_OK\n", hr);
724  refcount = IAVIStream_AddRef(stream);
725  ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
726 
727  hr = IAVIStream_QueryInterface(stream, &IID_IAVIEditStream, (void**)&edit);
728  ok(hr == S_OK, "QueryInterface for IID_IAVIEditStream failed: %08x\n", hr);
729  refcount = IAVIEditStream_AddRef(edit);
730  ok(refcount == 4, "refcount == %u, expected 4\n", refcount);
731  refcount = IAVIEditStream_Release(edit);
732 
733  hr = IAVIEditStream_QueryInterface(edit, &IID_IUnknown, (void**)&unk);
734  ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr);
735  refcount = IUnknown_AddRef(unk);
736  ok(refcount == 5, "refcount == %u, expected 5\n", refcount);
737  IUnknown_Release(unk);
738 
739  while (IAVIEditStream_Release(edit));
740 }
741 
743 {
744 
745  AVIFileInit();
752  test_COM();
755  AVIFileExit();
756 
757 }
#define ICMF_CHOOSE_ALLCOMPRESSORS
Definition: vfw.h:851
#define IAVIFile_QueryInterface(p, a, b)
Definition: vfw.h:1602
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM pstream, LONG pos, LPVOID format, LPLONG formatsize)
Definition: api.c:550
BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStreams, PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *ppOptions)
Definition: api.c:1429
DWORD dwStart
Definition: vfw.h:1012
WORD wLanguage
Definition: vfw.h:1009
#define REFIID
Definition: guiddef.h:118
api
Definition: notification.c:37
#define CloseHandle
Definition: compat.h:398
#define E_NOINTERFACE
Definition: winerror.h:2364
#define ckidSTREAMFORMAT
Definition: aviriff.h:125
#define AVIERR_NODATA
Definition: vfw.h:1757
#define listtypeSTREAMHEADER
Definition: vfw.h:892
HRESULT hr
Definition: shlfolder.c:183
static void test_COM_editstream(void)
Definition: api.c:713
DWORD dwFormatChangeCount
Definition: vfw.h:1020
static ULONG WINAPI unk_Release(IUnknown *iface)
Definition: api.c:588
static ULONG WINAPI unk_AddRef(IUnknown *iface)
Definition: api.c:581
DWORD dwRate
Definition: vfw.h:1011
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ckidAVIPADDING
Definition: vfw.h:916
IUnknown IUnknown_iface
Definition: api.c:545
DWORD dwInitialFrames
Definition: vfw.h:1014
REFIID riid
Definition: precomp.h:44
#define listtypeAVIHEADER
Definition: vfw.h:890
static void create_avi_file(const COMMON_AVI_HEADERS *cah, char *filename)
Definition: api.c:331
DWORD dwQuality
Definition: vfw.h:1016
char CHAR
Definition: xmlstorage.h:175
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
#define U(x)
Definition: wordpad.c:44
REFIID LPVOID * ppv
Definition: atlbase.h:39
LONG top
Definition: windef.h:292
#define IAVIStream_Release(p)
Definition: vfw.h:1177
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
WAVEFORMAT wf
Definition: mmsystem.h:1075
LONG ref
Definition: api.c:546
#define ckidSTREAMHEADER
Definition: aviriff.h:88
DWORD fccType
Definition: vfw.h:1004
static void test_COM_wavfile(void)
Definition: api.c:652
int winetest_interactive
ULONG WINAPI AVIFileRelease(PAVIFILE pfile)
Definition: api.c:292
LONG left
Definition: windef.h:291
static const DWORD audiostreamformat_pre[]
Definition: api.c:151
const char * filename
Definition: ioapi.h:135
struct pcmwaveformat_tag PCMWAVEFORMAT
LONG right
Definition: windef.h:293
AVIStreamHeader ash0
Definition: api.c:113
DWORD dwFlags
Definition: vfw.h:1006
Definition: send.c:47
#define OF_SHARE_DENY_WRITE
Definition: winbase.h:122
#define IAVIFile_AddRef(p)
Definition: vfw.h:1603
DWORD dwSuggestedBufferSize
Definition: vfw.h:1015
static void test_AVISaveOptions(void)
Definition: api.c:174
WORD nBlockAlign
Definition: mmsystem.h:1071
struct _test_info info[]
Definition: SetCursorPos.c:19
static struct unk_impl * impl_from_IUnknown(IUnknown *iface)
Definition: api.c:550
void WINAPI AVIFileInit(void)
Definition: api.c:176
long LONG
Definition: pedump.c:60
PCMWAVEFORMAT pcmwf
Definition: api.c:115
#define GENERIC_WRITE
Definition: nt_native.h:90
static void test_ash1_corruption2(void)
Definition: api.c:509
#define IAVIStream_AddRef(p)
Definition: vfw.h:1176
#define ICMF_CHOOSE_DATARATE
Definition: vfw.h:849
START_TEST(api)
Definition: api.c:742
static void test_default_data(void)
Definition: api.c:355
smooth NULL
Definition: ftsmooth.c:416
static const DWORD streamlist[]
Definition: api.c:121
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
DWORD dwSampleSize
Definition: vfw.h:1017
MainAVIHeader mah
Definition: api.c:112
static const CHAR testfilename[]
Definition: api.c:35
DEFINE_AVIGUID(CLSID_WAVFile, 0x00020003, 0, 0)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
DWORD dwScale
Definition: vfw.h:1010
DWORD nSamplesPerSec
Definition: audioclient.idl:42
HRESULT WINAPI CreateEditableStream(IAVIStream **editable, IAVIStream *src)
Definition: editstream.c:1029
static const DWORD deffh[]
Definition: api.c:39
HRESULT WINAPI EditStreamSetInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi, LONG size)
Definition: api.c:2101
struct _MainAVIHeader MainAVIHeader
HRESULT hres
Definition: protocol.c:465
#define FOURCC_LIST
Definition: mmsystem.h:565
#define trace
Definition: atltest.h:70
static const AVIStreamHeader defash0
Definition: api.c:61
LONG HRESULT
Definition: typedefs.h:77
struct common_avi_headers COMMON_AVI_HEADERS
const GUID IID_IUnknown
#define AVIERR_BADSIZE
Definition: vfw.h:1749
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
AVIStreamHeader ash1
Definition: api.c:114
HRESULT WINAPI AVIFileOpenA(PAVIFILE *ppfile, LPCSTR szFile, UINT uMode, LPCLSID lpHandler)
Definition: api.c:193
#define SetLastError(x)
Definition: compat.h:409
static const AVIStreamHeader defash1
Definition: api.c:79
static const MainAVIHeader defmah
Definition: api.c:46
ULONG WINAPI AVIStreamRelease(PAVISTREAM pstream)
Definition: api.c:450
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
Definition: api.c:544
RECT rcFrame
Definition: vfw.h:1018
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
static const WCHAR L[]
Definition: oid.c:1250
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define InterlockedDecrement
Definition: armddk.h:52
Definition: parse.h:22
DWORD fccHandler
Definition: vfw.h:1005
static void test_ash1_corruption(void)
Definition: api.c:473
GLuint GLuint stream
Definition: glext.h:7522
LONG WINAPI AVIStreamStart(PAVISTREAM pstream)
Definition: api.c:859
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define IS_INFO_UPDATED(m)
DWORD dwSampleSize
Definition: vfw.h:971
static void test_EditStreamSetInfo(void)
Definition: api.c:226
#define streamtypeAUDIO
Definition: aviriff.h:93
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static const DWORD videopropheader[]
Definition: api.c:139
DWORD fh[sizeof(deffh)]
Definition: api.c:111
static const IUnknownVtbl unk_vtbl
Definition: api.c:595
_In_ HANDLE hFile
Definition: mswsock.h:90
#define IAVIStream_QueryInterface(p, a, b)
Definition: vfw.h:1175
#define AVIERR_OK
Definition: vfw.h:1740
static const PCMWAVEFORMAT defpcmwf
Definition: api.c:98
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3234
#define streamtypeVIDEO
Definition: aviriff.h:92
#define ICMF_CHOOSE_KEYFRAME
Definition: vfw.h:848
HRESULT WINAPI AVIStreamInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi, LONG size)
Definition: api.c:497
#define S_OK
Definition: intsafe.h:59
#define CREATE_ALWAYS
Definition: disk.h:72
#define InterlockedIncrement
Definition: armddk.h:53
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2053
HRESULT WINAPI AVISaveOptionsFree(INT nStreams, LPAVICOMPRESSOPTIONS *ppOptions)
Definition: api.c:1482
static void test_amh_corruption(void)
Definition: api.c:452
#define IAVIEditStream_Release(p)
Definition: vfw.h:1511
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
#define formtypeAVI
Definition: vfw.h:889
#define ok(value,...)
Definition: atltest.h:57
#define listtypeAVIMOVIE
Definition: vfw.h:898
static void init_test_struct(COMMON_AVI_HEADERS *cah)
Definition: api.c:322
HRESULT WINAPI EditStreamSetNameA(PAVISTREAM pstream, LPCSTR szName)
Definition: api.c:2145
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
static void test_COM(void)
Definition: api.c:602
DWORD dwEditCount
Definition: vfw.h:1019
#define ckidAVIMAINHDR
Definition: vfw.h:891
const GUID IID_IPersistFile
HRESULT WINAPI AVIFileGetStream(PAVIFILE pfile, PAVISTREAM *avis, DWORD fccType, LONG lParam)
Definition: api.c:346
DWORD dwLength
Definition: vfw.h:1013
GLuint res
Definition: glext.h:9613
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define IAVIFile_Release(p)
Definition: vfw.h:1604
unsigned int ULONG
Definition: retypes.h:1
LONG bottom
Definition: windef.h:294
static HRESULT WINAPI unk_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: api.c:555
static const DWORD padding1[]
Definition: api.c:134
static const CHAR winetest0[]
Definition: api.c:33
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:399
#define ICQUALITY_HIGH
Definition: vfw.h:277
static const DWORD videostreamformat[]
Definition: api.c:127
void WINAPI AVIFileExit(void)
Definition: api.c:183
WORD wPriority
Definition: vfw.h:1008
static const CHAR winetest1[]
Definition: api.c:34
IUnknown * inner_unk
Definition: api.c:547
#define IAVIEditStream_QueryInterface(p, a, b)
Definition: vfw.h:1509
#define IAVIEditStream_AddRef(p)
Definition: vfw.h:1510