I'm playing about with one of the kernel driver examples in the Win7 DDK. I can modify compile and build my *.sys file. I can install it too with its INF (using device manager or devcon) or using the Service control manager directly. When I make the next change though and generate an updated *.sys file I seem to get a conflict between this new file and my now stopped driver (I've tried using Servcie Control Manager 'stop' and 'delete service' etc). If I reboot, I can install the new driver and run it fine. Similarly, if I choose uninstall in Device Manager, Windows prompts me to reboot.
So, how can one easily test incremental modifications to a kernal driver easily?
Thanks
Looking at the Setup API logs might be a good place to start: http://msdn.microsoft.com/en-us/library/ff550887%28v=VS.85%29.aspx
If devcon prompts for a reboot, you could look at the code in the DDK, debug why it's asking and dig into the issue that way as well.
Yes. sc stop <driver name> should stop your driver. If your driver is associated with a particular PnP devnode, it should be unloaded after the devnode is removed.
If you want to be able to unload your driver you have to set up a function which basically executes each time the driver is unloaded - most likely you will put code which frees allocated buffers and any other resource which might be "alive" during the lifecycle of the of the driver. Here is an example code:
VOID Unload(IN PDRIVER_OBJECT pDriverObject) {
//do whatever you like here
//this deletes the device
IoDeleteDevice( pDriverObject->DeviceObject);
return;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING regPath) {
//initialize your driver and the major function array
//set the unload function
pDriverObject->DriverUnload = &Unload;
}
Try compiling, signing, and loading this code:
#include <ntddk.h>
VOID OnUnload( IN PDRIVER_OBJECT driverObjectA ) {
DbgPrint("Unload\n");
}
NTSTATUS DriverEntry( PDRIVER_OBJECT driverObjectA, PUNICODE_STRING RegistryPath ){
DbgPrint("DriverEntry\n");
driverObjectA->DriverUnload = OnUnload;
return STATUS_SUCCESS;
}
Then download DebugView, unzip it, run it as administrator, and then "Capture Kernel" under the "Capture" menu item. Download, unzip, and run the OSR Driver Loader, register the driver, the "Start Service". You will observe a "DriverEntry" log message in DbgView. Now in the the OSR Driver loader, "Stop Service" and observe an Unload message. Hopefully that gets you going.
Related
I have an NPAPI plugin which makes use of SetWindowsHookEx under the hood to do some screen scraping. This plugin seems to run successfully on most machines I've tested. However, on one machine (32-bit Windows 7), when I'm running the plugin under Chrome (26.0.1410.43m), the call to SetWindowsHookEx crashes the process in which the plugin is hosted. It's not that SetWindowsHookEx returns an error - it simply crashes the process. And again, this only happens on one machine: it works fine on all the others we've tested.
But here's the weird thing. As you may know, Chrome has several ways of locating plugins. Normally, our setup.exe creates some registry entries that point to the plugin, like so (from the NSIS installer):
WriteRegStr HKLM "Software\MozillaPlugins\#alanta.com/WinVncCtl\" "Path" "$INSTDIR\npWinVnc.dll"
WriteRegStr HKLM "Software\MozillaPlugins\#alanta.com/WinVncCtl\" "ProductName" "Alanta Remote Desktop Server"
WriteRegStr HKLM "Software\MozillaPlugins\#alanta.com/WinVncCtl\MimeTypes\application/x-alanta-vnc" "Description" "Alanta's VNC Server NPAPI Plugin"
When Chrome loads the plugin from that location, it crashes on the SetWindowsHookEx call.
However, if I uninstall the plugin, then copy exactly the same DLL to %ProgramFiles%\Mozilla Firefox\Plugins\, then Chrome loads and runs the plugin just fine, and the call to SetWindowsHookEx() succeeds.
For what it's worth, here's the actual (pretty bog-standard) call:
// Add the CallWnd hook
hCallWndHook = SetWindowsHookEx(
WH_CALLWNDPROC, // Hook in before msg reaches app
(HOOKPROC) CallWndProc, // Hook procedure
hInstance, // This DLL instance
0L // Hook in to all apps
// GetCurrentThreadId() // DEBUG : HOOK ONLY WinVNC
);
The debugger indicates that all the parameters are pointing to legitimate, valid things.
Any suggestions for troubleshooting this? Anybody aware of any weirdnesses in SetWindowsHookEx that might show up in this scenario?
EDIT: The CallWndProc looks like this:
LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// Do we have to handle this message?
if (nCode == HC_ACTION)
{
// Process the hook if the WinVNC thread ID is valid
if (vnc_thread_id)
{
CWPSTRUCT *cwpStruct = (CWPSTRUCT *) lParam;
HookHandle(cwpStruct->message, cwpStruct->hwnd, cwpStruct->wParam, cwpStruct->lParam);
}
}
// Call the next handler in the chain
return CallNextHookEx (hCallWndHook, nCode, wParam, lParam);
}
Breakpoints in the CallWndProc don't seem to get hit, so I suspect that the crash is happening during the setting of the hook rather than during its later processing.
If the same DLL behaves differently when placed in a different directory, it suggests this is changing the order in which plugins load.
(The directory a DLL loads from does not affect the search path used to locate and load its dependencies)
I would certainly take a look at other plugins being loaded on the same system and see if their presence is triggering (or perhaps even responsible for) your crash.
After that, I suggest uninstalling and reinstalling Chrome, possibly in a new directory, in case one of the Chrome binaries is corrupted or subverted.
Turns out that it was an aggressive security program. Apparently its heuristics allowed some DLLs through while not allowing others. It was killing the hosting process as soon as it saw the call to SetWindowsHookEx(). Replacing it with something reasonable fixed the problem.
I'm using WinLIRC with IR receiver connected to serial port COM1 on Windows 7 x64. WinLIRC is added to Startup folder (Start->All applications->Startup) so it starts every time I log in. Very often (but not all the time) I see initialization error messages from WinLIRC, which continue for some time (couple of minutes) if I retry initialization, and after some retries it initializes correctly and works fine. If I remove it from Startup and start manually at any other moment it starts without errors.
I've downloaded WinLIRC sources and added MessageBox calls here and there so I can see what happens during initialization and found out that CreateFile call fails:
if((hPort=CreateFile(
settings.port,GENERIC_READ | GENERIC_WRITE,
0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0))==INVALID_HANDLE_VALUE)
{
char buffer[256];
sprintf_s(buffer, "CreateFile(%s) failed with %d", settings.port, GetLastError());
MessageBox(NULL, buffer, "debug", MB_OK);
hPort=NULL;
return false;
}
I see message box saying "CreateFile(COM1) failed with 5", and 5 is an error code for "Access denied" error according to this link.
So the question is why opening COM-port can fail with such error right after booting Windows and proceed normally few seconds or minutes later?
Update: the COM-port is the real one.
Update2: regarding the other application that opens serial port before WinLIRC. I did the following: I put Process Explorer to the Startup folder so it start on log in also, then rebooted. As soon as process explorer started I ran "Find Handle or Dll" dialog, put "Serial0" to the input and hit "Search". By that moment WinLIRC had already shown message box saying "CreateFile(COM1) failed with 5". Then I waited till the process explorer search ends, seen that it found nothing, then tried to reinitialize WinLIRC and it failed again. So I suggest that it is not the case of serial port being opened by other application. If anyone can suggest a better way to check it, I'll happily recheck.
When I search for "Serial0" in process explorer while WinLIRC is running it finds the winlirc.exe process, so it looks like it is correct term to search.
Update3: regarding the serial mouse driver. It is not listed in device manager, so I wasn't able to disable it there, however I have found this instructions on how to disable sermouse service and it didn't help.
Update4: one more thing I forgot to mention. It happens only if I log in soon after booting PC. If I leave windows on log in screen for several minutes and log in later, then WinLIRC initializes without any problems always.
Update5: Unfortunately, I don't have access to the computer that had this problem reproducing, so I can't experiment anymore.
It takes time to initialize the port.
Your application will run absolutely fine on windows XP.
Windows7's serial ports are virtual.
You can run a small code and check it out
using System.IO.Ports;
private void Form1_Load(object sender, EventArgs e)
{
string[] ports = System.IO.Ports.SerialPort.GetPortNames();
comboBox1.Items.Add("None");
foreach (string port in ports)
comboBox1.Items.Add(port);
comboBox1.SelectedIndex = 0;
}
This will return you the list of serial port. Check the status of it and display it on message box.
Make this code and run at startup. You'll get the root cause.
Here some links one has to visit before plunging into the magic world of serial programming in Windows :)
A detailed explanation of serial programming in Windows:
http://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c5425/Serial-Communication-in-Windows.htm
a little bit outdated (the site states 1999-2003 so yes, it's outdated) but absolutely useful:
http://www.flounder.com/serial.htm
The ShellExecuteEx Win32 function call has a flag SEE_MASK_FLAG_NO_UI in its SHELLEXECUTEINFO structure, which should suppress any error dialogs which could be displayed because of an error when launching an application.
The MSDN documentation here is quite explicit about it:
SEE_MASK_FLAG_NO_UI
0x00000400. Do not display an error message box if an error occurs.
In my case, I am launching a .NET executable on a Windows XP system where no .NET is installed. I systematically receive the following message, displayed by Windows in a dialog window:
Xxx.exe - Application Error
The application failed to initialize properly (0xc0000135).
Click on OK to terminate the application.
[ OK ]
I don't want the user to have to deal with this message. I'd rather get back an error code from ShellExecuteEx and be able to handle it gracefully in my program. Here is the code snippet which I am using to start the external executable:
#include <windows.h>
int wmain(int argc, wchar_t* argv[])
{
SHELLEXECUTEINFO info;
memset(&info, 0, sizeof(SHELLEXECUTEINFO));
info.cbSize = sizeof(SHELLEXECUTEINFO);
info.fMask = SEE_MASK_FLAG_NO_UI;
info.lpVerb = L"open";
info.lpFile = L"Xxx.exe";
info.nShow = SW_SHOW;
return ShellExecuteEx (&info);
}
Is there an official way of suppressing the error message if .NET is not present on the system? Or do I have to check for this specific condition myself before executing the application (but I do not know in advance if it is a .NET app or a native app). And what if the app I am starting is missing some DLLs, for instance?
The flag only tells the shell to not display an error message. It doesn't affect the UI of the process that got started. The .NET .exe really did get started so ShellExecuteEx() did it's job and saw no errors. That it decided to bomb afterwards and let the user know about it is not something you can easily fix.
why don't you use the CreateProcess function
I am creating a shell extension in C++ (ATL 9) using Visual Studio 2008. The Shell Extension creates a global MSXML2::IXMLDOMDocumentPtr object m_XmlDoc in the module class. This m_XmlDoc is then used in the extension by all classes to read xml document.
The problem that I am facing is with Internet explorer. When the Shell Extension is active and I open/close internet explorer, I get a debug dialog and IE crashes. The error message says "Unhandled exception at 0x6aac30f1 in iexplore.exe: 0xC0000005: Access violation reading location 0x03050970."
When I click "break" on the message window, It takes me to the "Release" method of COM Smart Pointer and the error seems to be on
m_pInterface->Release();
This call was made from Module's destructor and also the value of m_pInterface is not NULL. I think maybe internet explorer is using the XML DOM and the call to Release creates some problem in it.
MSXML2::IXMLDOMDocumentPtr m_XmlDoc;
In _AtlModule.Init() method
::CoInitialize(NULL);
m_XmlDoc.CreateInstance(MSXML2::CLSID_DOMDocument40);
dllMain code:
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
::CoInitialize(NULL);
if (dwReason == DLL_PROCESS_ATTACH)
{
_AtlModule.Init();
CreateImageLists();
::DisableThreadLibraryCalls(hInstance);
}
hInstance;
return _AtlModule.DllMain(dwReason, lpReserved);
}
the use of DisableThreadLibraryCalls is discouraged, you seen it?
There are at least two problems with your code as posted:
You're calling CoInitialize in DllMain.
You're creating a COM object in DllMain.
It wouldn't surprise me if you're doing something in CreateImageLists() which you also shouldn't be doing in DllMain.
Also, the reason that your crash was "fixed" by not using the smart pointer is because now you're not actually releasing the object anymore. Your code is broken, and not releasing the reference isn't a valid way to fix anything.
I would suggest that you read, and then re-read, the documentation for DllMain paying particular attention to the things you should never do within your implementation of the function. As you'll see right up front:
Warning There are serious limits on what you can do in a DLL entry point. To provide more complex initialization, create an initialization routine for the DLL. You can require applications to call the initialization routine before calling any other routines in the DLL.
I suspect once you read it, and fix your code to create the COM object at a valid time, and release it at a valid time, your shell extension will stop crashing.
The problem was because of the COM Smart Pointer used for XmlDomDocument. I changed it to a normal pointer and it is working fine even in Vista.
This problem has a different behaviour in XP and Vista. In XP, I was getting an unhandled exception when I closed Internet Explorer. In Vista, I was not able to browse the virtual drive.
When an application crashes on Windows and a debugger such as Visual Studio is installed the following modal dialog appears:
[Title: Microsoft Windows]
X has stopped working
A problem caused the program to stop
working correctly. Windows will close
the program and notify you if a
solution is available.
[Debug][Close Application]
Is there a way to disable this dialog? That is, have the program just crash and burn silently?
My scenario is that I would like to run several automated tests, some of which will crash due to bugs in the application under test. I don't want these dialogs stalling the automation run.
Searching around I think I've located the solution for disabling this on Windows XP, which is nuking this reg key:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
However, that did not work on Windows Vista.
To force Windows Error Reporting (WER) to take a crash dump and close the app, instead of prompting you to debug the program, you can set these registry entries:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting]
"ForceQueue"=dword:00000001
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\Consent]
"DefaultConsent"=dword:00000001
After this is set, when your apps crash, you should see *.hdmp and *.mdmp files in:
%ALLUSERSPROFILE%\Microsoft\Windows\WER\
See here:
http://msdn.microsoft.com/en-us/library/bb513638.aspx
regedit
DWORD HKLM or HKCU\Software\Microsoft\Windows\Windows Error Reporting\DontShowUI = "1"
will make WER silently report. Then you can set
DWORD HKLM or HKCU\Software\Microsoft\Windows\Windows Error Reporting\Disabled = "1"
to stop it from talking to MS.
I'm not sure if this refers to exactly the same dialog but here is an alternative approach from Raymond Chen:
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
I had to disable this for release automation work on Windows 64-bits for Firefox and I did the following:
gpedit.msc
Computer configuration -> Administrative Templates
Windows Components -> Windows Error Reporting
Set "Prevent display of the user interface for critical errors" to Enabled
It is similar what was accomplished for Customer Experience reporting in:
http://www.blogsdna.com/2137/fix-windows-installer-explorer-update-has-stopped-working-in-windows-7.htm
In my context, I only want to suppress the popup for my unit tests and not for the entire system. I've found that a combination of functions are needed in order to suppress these errors, such as catching unhandled exceptions, suppressing run time checks (such as the validity of the stack pointer) and the error mode flags. This is what I've used with some success:
#include <windows.h>
#include <rtcapi.h>
int exception_handler(LPEXCEPTION_POINTERS p)
{
printf("Exception detected during the unit tests!\n");
exit(1);
}
int runtime_check_handler(int errorType, const char *filename, int linenumber, const char *moduleName, const char *format, ...)
{
printf("Error type %d at %s line %d in %s", errorType, filename, linenumber, moduleName);
exit(1);
}
int main()
{
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)&exception_handler);
_RTC_SetErrorFunc(&runtime_check_handler);
// Run your tests here
return 0;
}
In WPF application
[DllImport("kernel32.dll", SetLastError = true)]
static extern int SetErrorMode(int wMode);
[DllImport("kernel32.dll")]
static extern FilterDelegate SetUnhandledExceptionFilter(FilterDelegate lpTopLevelExceptionFilter);
public delegate bool FilterDelegate(Exception ex);
public static void DisableChashReport()
{
FilterDelegate fd = delegate(Exception ex)
{
return true;
};
SetUnhandledExceptionFilter(fd);
SetErrorMode(SetErrorMode(0) | 0x0002 );
}
You have to implement an unhandled exception filter which simply quits your application, then set that filter function with SetUnhandledExceptionFilter().
If you're using the secure CRT, you also have to provide your own invalid parameter handler and set this with _set_invalid_parameter_handler().
This blog post has some information too:
http://blog.kalmbachnet.de/?postid=75
During test you can run with a 'debugger' like ADPlus attached which can be configured in many useful ways to collect data (minidumps) on errors and yet prevent the modal dialog problems you state above.
If you want to get some useful information when your app crashes in production you can configure Microsoft Error reporting to get something similar to ADPlus data.
This isn't a direct answer to the question since this is a workaround and the question is about how to disable that feature, but in my case, I'm a user on a server with limited permissions and cannot disable the feature using one of the other answers. So, I needed a workaround. This will likely work for at least some others who end up on this question.
I used autohotkey portable and created a macro that once a minute checks to see if the popup box exists, and if it does, clicks the button to close the program. In my case, that's sufficient, and leaves the feature on for other users. It requires that I start the script when I run the at-risk program, but it works for my needs.
The script is as follows:
sleep_duration = 60000 ; how often to check, in milliseconds.
; 60000 is a full minute
Loop
{
IfWinExist, ahk_class #32770 ; use autohotkey's window spy to confirm that
; ahk_class #32770 is it for you. This seemed to be consistent
; across all errors like this on Windows Server 2008
{
ControlClick, Button2, ahk_class #32770 ; sends the click.
; Button2 is the control name and then the following
; is that window name again
}
Sleep, sleep_duration ; wait for the time set above
}
edit: A quick flag. When other things are up, this seems to attempt to activate controls in the foreground window - it's supposed to send it to the program in the background. If I find a fix, I'll edit this answer to reflect it, but for now, be cautious about using this and trying to do other work on a machine at the same time.
After trying everything else on the internet to get rid of just in time debugger, I found a simple way that actually worked and I hope will help someone else.
Go to Control Panel
Go to Administrative Tools
Go to Services
Look down the list for Machine Debug Manager
Right Click on it and click on Properties
Under the General Tab, look for Start Up Type
Click on Disable.
Click on Apply and OK.
I haven't seen the debugger message since, and my computer is running perfectly.
Instead of changing values in the registry you can completly disable the error reporting on Windows Server 2008 R2, Windows Server 2012 and Windows 8 with: serverWerOptin /disable
https://technet.microsoft.com/en-us/library/hh875648(v=ws.11).aspx