Continuing investigation on a embedded WindowsMediaPlayer problem, i am trying to do simple file playback via a DirectShow in-process server:
::CoInitializeEx(0, COINIT_MULTITHREADED);
CComPtr<IGraphBuilder> spGraph;
spGraph.CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER);
CComQIPtr<IMediaControl> spMediaControl(spGraph);
// ... later:
spGraph->RenderFile(L"c:\\foo.wav", 0); // fails with VFW_E_BAD_KEY
spMediaControl->Run();
Interestingly, this runs fine on both systems i tested on (Windows XP 32 & x64) when doing it in a stand-alone application.
It however fails in my real use-case, a NPAPI based browser plugin - i.e. a DLL loaded into Firefox/Chrome/Opera.
Does anyone have an idea what could be going wrong here?
Or ideas on what else to try?
Update: also asked on the Microsoft forums.
Update2:
IGraphBuilder::AddSourceFilter(path,path,&base) already fails with the following registry calls (as seen in process monitor):
"RegOpenKey","HKCU\Software\Classes\c","NAME NOT FOUND","Desired Access: Query Value, Maximum Allowed"
"RegOpenKey","HKCU\Software\Classes\Media Type\Extensions\.wav","NAME NOT FOUND","Desired Access: Read"
"RegOpenKey","HKCU\Software\Classes\Media Type","NAME NOT FOUND","Desired Access: Read"
It is reading the key from the wrong hive. It should use HKLM, not HKCU. The most likely reason for this is registry virtualization.
Related
I have downloaded a Windows 7 x32 Enterprise (IE11) hyper-v image from Microsoft website to test a research project.
For some reason all the Ntdll functions I call (syscall) return STATUS_WAIT_0. I mean all of them that I have tested including RtlGetVersion, NtAllocateVirtualMemory, NtCreateFile and more.
Could this be because it's a virtual machine ? Or could it be because I do direct system calls ?
Please advise, I have tested my project under non-virtual machines including latest Windows 10 and it works fine so I doubt it's my code.
Update:
STATUS_WAIT_0 can be considered as STATUS_SUCCESS since it's value is both 0.
Ntdll function basically returns a NTSTATUS, like RtlGetVersion,NtAllocateVirtualMemory,NtCreateFile and more.
The following document contains the common usage details of the NTSTATUS values
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
Return value/code:
0x00000000
STATUS_SUCCESS/STATUS_WAIT_0
Description:
The operation completed successfully.
The caller specified WaitAny for WaitType and one of the dispatcher objects in the Object array has been set to the signaled state.
My C++ program calls LoadLibraryEx() to load a third party DLL. The result is a null handle - it fails to load. A call to GetLastError() returns zero afterwards which isn't of much use but at least it's not a missing DLL file.
The code goes something like this:
HINSTANCE instance = ::LoadLibraryExW(
path, 0, LOAD_WITH_ALTERED_SEARCH_PATH );
if (instance == 0)
{
DWORD lastError = GetLastError();
LOG( "Failed to load, error code is " +
LastErrorAsString( lastError ));
return E_FAIL;
}
I cannot access that machine - I can only deploy code there and observe logs uploaded into network storage.
How would I programmatically find why the DLL fails to load?
Probably your dll can be found but it has a dependency on a dll that cannot found on the remote machine.
If you cannot use Dependency Walker then you can try to use techniques as described in articles such as this:
How to determine a windows executables DLL dependencies programatically?
Okay, so I checked better - and indeed there was another WinAPI call which caused "last error" to be overwritten after LoadLibraryEx(). It was hidden deep inside several layers of C++ helper objects so I didn't notice it earlier. So it was a bug in the caller code and the real "last error" was non-zero.
It looks like the problem is likely to be third-party software that has installed a hook or other anti-virus measure, the hook might be buggy and not setting the correct last error code.
As a troubleshooting measure, you should try LdrLoadDll instead of LoadLibraryEx.
Note that this is an undocumented internal function, so you might prefer not to use it in production code, but it would be a useful troubleshooting step as it should produce a more useful error code.
it seems that location API is legacy(?). It does not work the GetReport(...) but works ok if you set RegisterForReport(...) The error I get is the follow
drivers\mobilepc\locationconvergence\api\winlegacyapi\dllapi\legacyapiimpltemplate.h(197)\LocationApi.dll!06552CA7: (caller: 06552D34) ReturnHr[PreRelease](1) tid(478) 8007139F The group or resource is not in the correct state to perform the requested operation.
[CLocationApiImplTemplate<class CLegacyPositionRequest,&struct __s_GUID const _GUID_e4e915a9_8344_4f88_9326_2adc071d4ff6>::GetReportInterval(!m_fRegistered)]
SalesMan::AGW_CLASS::AGWLocationWin8::GetLocation> HR=8007139F
SalesMan::AGW_CLASS::AGWLocationWin8::GetLocation> reportInterval=0
drivers\mobilepc\locationconvergence\api\winlegacyapi\dllapi\legacyapiimpltemplate.h(158)\LocationApi.dll!06554401: (caller: 06554448) ReturnHr[PreRelease](2) tid(478) 800700E8 The pipe is being closed.
[CLocationApiImplTemplate<class CLegacyPositionRequest,&struct __s_GUID const _GUID_e4e915a9_8344_4f88_9326_2adc071d4ff6>::GetReport(m_pLatLongReport == nullptr)]
drivers\mobilepc\locationconvergence\api\winlegacyapi\dllapi\legacypositionrequest.cpp(80)\LocationApi.dll!06554469: (caller: 06552BF2) ReturnHr[PreRelease](3) tid(478) 800700E8 The pipe is being closed.
[CLegacyPositionRequest::GetReport(__super::GetReport(ReportType, ppLocationReport))]
I must say here that RequestPermissions(...) works fine and returns OK. The same application on windows 8.1 works fine.
Anyone any idea?
Thank you in advance
George
I bypassed the problem by implementing the event driven location report.
Probably Windows 10 initialize slower the location than windows 8 , since the hardware is the same. I give it a 3 seconds report interval and reports back the lat/lon
George
Good Day,
I have searched the Internet tirelessly trying to find an example of how to start Windows Speech Training from with in my VB.Net Speech Recognition Application.
I have found a couple examples, which I can not get working to save my life.
One such example is on the Visual Studios Fourms:
HERE
this particular example users the "Process.Start" call to try and start the Speech Training Session. However this does not work for me. Here is the exmaple from that thread:
Process.Start("rundll32.exe", "C:\Windows\system32\speech\speechux\SpeechUX.dll, RunWizard UserTraining")
What happens is I get and error that says:
There was a problem starting
C:\Windows\system32\speech\speechux\SpeechUX.dll
The specified module could not be found
So I tried creating a shortcut (.lnk) file and thought I could access the DLL this way. My short cut kind of does the same thing. In the short cut I call the "rundll32.exe" with parameters:
C:\Windows\System32\rundll32.exe "C:\Windows\system32\speech\speechux\SpeechUX.dll" RunWizard UserTraining
Then in my VB.Net application I use the "Process.Start" and try to run the shortcut.
This also gives me the same error. However the shortcut itself will start the SPeech Training session. Weird?!?
So, I then took it one step further, to see if it has something to do with my VB.Net Application and the "Process.Start" Call.
I created a VBScript, and using "Wscript.Shell" I point to the Shortcut.
Running the VBScript calls the Shortcut and low and behold the Speech Training starts!
Great! But...
when I try to run the VBscript from my VB.net Application, I get that error again.
What the heck is going on here?
Your problem likely is that your program is compiled as 32-bit and your OS is 64-bit, and thus, when you try to access "C:\Windows\System32\Speech\SpeechUX\SpeechUX.dll" from your program, you're really accessing "C:\Windows\SysWOW64\Speech\SpeechUX\SpeechUX.dll" which, as rundll32.exe is reporting doesn't exist.
Compile your program as 64-bit instead or try the pseudo directory %SystemRoot%\sysnative.
Also, instead of rundll32.exe, you may want to just run SpeechUXWiz.exe with an argument.
Eg.
private Process StartSpeechMicrophoneTraining()
{
Process process = new Process();
process.StartInfo.FileName = System.IO.Path.Combine(Environment.SystemDirectory, "speech\\speechux\\SpeechUXWiz.exe");
process.StartInfo.Arguments = "MicTraining";
process.Start();
return process;
}
private Process StartSpeechUserTraining()
{
Process process = new Process();
process.StartInfo.FileName = System.IO.Path.Combine(Environment.SystemDirectory, "speech\\speechux\\SpeechUXWiz.exe");
process.StartInfo.Arguments = "UserTraining";
process.Start();
return process;
}
Hope that helps.
Read more about Windows 32-bit on Windows 64-bit at http://en.wikipedia.org/wiki/WoW64
or your problem specifically at http://en.wikipedia.org/wiki/WoW64#Registry_and_file_system
If you are using a 64bit OS and want to access system32 folder you must use the directory alias name, which is "sysnative".
"C:\windows\sysnative" will allow you access to system32 folder and all it's contents.
Honestly, who decided this at Microsoft is just silly!!
I need to decompile a windows program which the source code was lost for a long time.
I am using boomerang in Windows 7 for this. However, it looks broken, gives this message and quits:
Could not open dynamic loader library Win32BinaryFile.dll (error #998)
Googling about it gives no useful results. Looking in the boomerang source code, it is apparently coming from this:
00137 hModule = LoadLibraryA(libName.c_str());
00138 if(hModule == NULL) {
00139 int err = GetLastError();
00140 fprintf( stderr, "Could not open dynamic loader library %s (error #%d)\n", libName.c_str(), err);
00141 fclose(f);
00142 return NULL;
00143 }
I.e. LoadLibraryA is failing with the status 998.
What could I do to fix that?
Edit, four hours later:
The program that I want to decompile is a work that me and a friend implemented in 2005. The source just gone in the mean time without we seeing that. Now, in 2013, when we searched it, nothing was found. In retrospect, it was probably lost in 2008 or in 2010, two occasions where my computer hardware crashed and I needed to get a new computer (and lost a lot of data with that). We had several backups scattered in several places, but after an exhaustive search, I found nothing.
I know that since boomerang is open source, I could just get its source code and hack it around. However, that sort of task is not what I originally intended to do, since the focus is just to decompile my program and I guess that I am missing something simple, since it can't load the DLL while it is clearly there.
I don't need the exact code back, just a sketch of what were the exact details of the algorithm that were implemented. Having that, I can rewrite the rest again.