{"id":757,"date":"2009-01-17T09:54:27","date_gmt":"2009-01-17T07:54:27","guid":{"rendered":"https:\/\/alax.info\/blog\/?p=757"},"modified":"2009-01-17T10:00:11","modified_gmt":"2009-01-17T08:00:11","slug":"amcap-issue","status":"publish","type":"post","link":"https:\/\/alax.info\/blog\/757","title":{"rendered":"AMCap issue"},"content":{"rendered":"<p>While playing around with a camera DirectShow video source filter, <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms778964.aspx\">AMCap<\/a>, which is widely used sample and which I believed to be very stable, started crashing in an inner call CDeviceMoniker::IsEqual:<\/p>\n<pre> \tdevenum.dll!CDeviceMoniker::IsEqual()  + 0x13 bytes\r\n&gt;\tAmCap.exe!ChooseDevices(IMoniker * pmVideo=0x003e9a38, IMoniker * pmAudio=0x00000000)  Line 2672 + 0x2a bytes\tC++\r\n \tAmCap.exe!ChooseDevices(wchar_t * szVideo=0x0013f5b8, wchar_t * szAudio=0x0013edb0)  Line 2753 + 0x13 bytes\tC++\r\n \tAmCap.exe!AppInit(HINSTANCE__ * hInst=0x00400000, HINSTANCE__ * hPrev=0x00000000, int sw=1)  Line 379 + 0x13 bytes\tC++\r\n \tAmCap.exe!WinMain(HINSTANCE__ * hInst=0x00400000, HINSTANCE__ * hPrev=0x00000000, char * szCmdLine=0x00161f32, int sw=1)  Line 453 + 0x11 bytes\tC++\r\n \tAmCap.exe!__tmainCRTStartup()  Line 578 + 0x35 bytes\tC\r\n \tAmCap.exe!WinMainCRTStartup()  Line 403\tC\r\n \tkernel32.dll!_BaseProcessStart@4()  + 0x23 bytes<\/pre>\n<p>It appeared that while setting a checkmark on proper menu item the code does not check for the moniker tobe not NULL and a NULL IMoniker pointer passed as an argument into <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms678408(VS.85).aspx\">IMoniker::IsEqual<\/a> is not checked inside devenum.dll (which is obviously a bug for an API entry).<\/p>\n<p>To hotfix the problem, it is necessary to add an extra check near line 2650 of amcap.cpp:<\/p>\n<pre>    int i;\r\n    for(i = 0; i &lt; NUMELMS(gcap.rgpmVideoMenu); i++)\r\n    {\r\n        if(gcap.rgpmVideoMenu[i] == NULL)\r\n            break;\r\n<span style=\"color: #ff0000;\">        \/\/ HOTFIX: Avoid calling IMoniker::IsEqual(NULL) due to possible memory access violation\r\n        if(!gcap.pmVideo)\r\n            continue;\r\n<\/span>        CheckMenuItem(GetMenu(ghwndApp),\r\n            MENU_VDEVICE0 + i,\r\n            (S_OK == gcap.rgpmVideoMenu[i]-&gt;IsEqual(gcap.pmVideo)) ? MF_CHECKED : MF_UNCHECKED);\r\n    }\r\n\r\n    for(i = 0; i &lt; NUMELMS(gcap.rgpmAudioMenu); i++)\r\n    {\r\n        if(gcap.rgpmAudioMenu[i] == NULL)\r\n            break;\r\n<span style=\"color: #ff0000;\">        \/\/ HOTFIX: Avoid calling IMoniker::IsEqual(NULL) due to possible memory access violation\r\n        if(!gcap.pmAudio)\r\n            continue;\r\n<\/span>        CheckMenuItem(GetMenu(ghwndApp), MENU_ADEVICE0 + i,\r\n            (S_OK == gcap.rgpmAudioMenu[i]-&gt;IsEqual(gcap.pmAudio)) ? MF_CHECKED : MF_UNCHECKED);\r\n    }<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>While playing around with a camera DirectShow video source filter, AMCap, which is widely used sample and which I believed to be very stable, started crashing in an inner call CDeviceMoniker::IsEqual: devenum.dll!CDeviceMoniker::IsEqual() + 0x13 bytes &gt; AmCap.exe!ChooseDevices(IMoniker * pmVideo=0x003e9a38, IMoniker * pmAudio=0x00000000) Line 2672 + 0x2a bytes C++ AmCap.exe!ChooseDevices(wchar_t * szVideo=0x0013f5b8, wchar_t * szAudio=0x0013edb0) Line&hellip; <\/p>\n<p><a class=\"moretag\" href=\"https:\/\/alax.info\/blog\/757\">Read the full article<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,10],"tags":[160,63,78,161,488],"class_list":["post-757","post","type-post","status-publish","format-standard","hentry","category-technology","category-video","tag-amcap","tag-bug","tag-directshow","tag-exception","tag-source"],"_links":{"self":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/757","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/comments?post=757"}],"version-history":[{"count":0,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/posts\/757\/revisions"}],"wp:attachment":[{"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/media?parent=757"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/categories?post=757"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alax.info\/blog\/wp-json\/wp\/v2\/tags?post=757"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}