How to prevent Windows from caching Com Class info? - windows

Windows 7 is caching some of the COM class information. Older OSs didn't do this. After the OS looks up theHKCU\Software\Classes\CLSID\{GUID}\LocalServer32 value, it caches the value, and doesn't look it up again.
When we update our software, we place the new updates in a different directory, and then update the HKCU\Software\Classes\CLSID\{GUID}\LocalServer32 value to reflect the new path. The next time the software runs, it will use the latest files if running under older Windows OSs. However, on Windows 7, it will continue to use the older file, until the OS is rebooted.
I ran process monitor, and discovered that under Windows 7, it never reads the registry key again, after the first read. On older OSs, it reads that key every time.
My question is: Is there any way to force Windows 7 to re-read the LocalServer32 information from the HKCU hive each time a new out of proc COM object is created?

I have only been able to solve this problem by...
1: Stopping the Process
2: explicitly unregistering using regsvr32 the library ( or exename /unregserver)
3: Registering the new component
4: Starting the process back up.
I would suspect that it is the Un Reg part that is failing for you. If you are just changing the registry key directly then you should call RegSvr32 /u instead.
Also make sure the new directory location is the current directory when you call RegSvr32.
Note that I have always stopped the process and then unregistered, this is probably a significant detail.

As this is a top result in Google for this narrow-ish problem, I thought it would be valuable to add my troubleshooting outcome for this problem.
I found this response on SO: C# : How to change windows registry and take effect immediately
And linked solution from that answer: Registry Watcher C#
Both of which seem viable options for managing changed keys without forcing a reboot. For us (like the OP) this was when installing updates. For us (possibly unlike the OP) this is infrequent and we decided the effort to implement and test a fix as described was outweighed by the simple solution of requiring a reboot: a process Windows users have come to expect with installing software anyway.

Related

Create file or registry key without calling NTDLL.DLL

I know that ntdll is always present in the running process but is there a way (not necessarily supported/stable/guaranteed to work) to create a file/key without ever invoking ntdll functions?
NTDLL is at the bottom of the user-mode hierarchy, some of its functions switch to kernel mode to perform their tasks. If you want to duplicate its code then I suppose there is nothing stopping you from decompiling NtCreateFile to figure out how it works. Keep in mind that on 32-bit Windows there are 3 different instructions used to enter kernel mode (depending on the CPU type), the exact way and where the transition code lives changes between versions and the system call ids change between versions (and even service packs). You can find a list of system call ids here.
I assume you are doing this to avoid people hooking your calls? Detecting your calls? Either way, I can't recommend that you try to do this. Having to test on a huge set of different Windows versions is unmanageable and your software might break on a simple Windows update at any point.
You could create a custom kernel driver that does the work for you but then you are on the hook for getting all the security correct. At least you would have documented functions to call in the kernel.
Technically, registry is stored in %WINDIR%\System32\config / %WINDIR%\SysWOW64\config, excepted your own user's registry which is stored in your own profile, in %USERPROFILE%\NTUSER.DAT.
And now, the problems...
You don't normally have even a read access to this folder, and this is true even from an elevated process. You'll need to change (and mess up a lot...) the permissions to simply read it.
Even for your own registry, you can't open the binary file - "Sharing violation"... So, for system/local machine registries... You can't in fact open ANY registry file for the current machine/session. You would need to shut down your Windows and mount its system drive in another machine/OS to be able to open - and maybe edit - registry files.
Real registry isn't a simple file like the .reg files. It's a database (you can look here for some elements on its structure). Even when having a full access to the binary files, it won't be fun to add something inside "from scratch", without any sotware support.
So, it's technically possible - after all, Windows does it, right? But I doubt that it can be done in a reasonable amount of time, and I simply can't see any benefit from doing that since, as you said, ntdll is ALWAYS present, loaded and available to be used.
If the purpose is to hack the current machine and/or bypass some lack of privileges, it's a hopeless approach, since you'll need even more privileges to do it - like being able to open your case and extract the system drive or being able to boot on another operating system on the same machine... If it's possible, then there is already tools to access the offline Windows, found on a well-known "Boot CD", so still no need to write in registry without any Windows support.

Windows Driver - How do I determine if Windows is in the process of booting, or has already booted?

I'm trying to develop a dual purpose driver that performs certain tasks at boot time, and other unrelated tasks after Windows has already started. It's developed as a boot start driver. I understand that the proper way to do this may be to develop 2 separate drivers, but I'd prefer to only go through the WinQual process once. There's also the added benefit of performing only one driver install in my app versus two. It needs to work on Vista through Win8 x86 & 64.
So what I'm really looking for is a safe way to determine in DriverInit if the system is in the process of booting, or if it's already up and running. The driver will initially be utilized when Windows has already started, then enabled at boot time after the next reboot. The DriverInit code needs to be different for both scenarios.
Is there a registry key that is or is not present?
Can I determine if a user is logged-in in DriverInit?
Is there a call I can make that will determine if Windows is booting?
I'm not an expert at driver writing, so thanks in advance for any advice.
Technically, glagolig's answer is probably the correct way to solve this.
The solution for my particular issue was a little different. There are 2 mutually exclusive use cases were the driver is either needed as a SERVICE_DEMAND_START driver after Windows is up and running, or as a SERVICE_BOOT_START driver with boot time functionality. The situation never arises were I need the functionality of both cases at the same time in the same Windows session.
The driver is initially installed as a SERVICE_DEMAND_START driver (this is the one that is going to WinQual). It is then changed to SERVICE_BOOT_START in the registry on the new drive that will be booted. All the driver entry points (DriverEntry, AddDevice, etc) that are different for each use case read the 'Start' value in the driver's service registry key to determine how it needs to operate.
It hasn't passed yet, but I'm fairly certain that I can change the start type of the driver in the registry without affecting Window's digital signature enforcement.
At the time boot-start drivers are loaded Windows has not created any user-mode processes yet. Try to acquire a handle to some process that is supposed to be created later on during Windows startup. For example, smss.exe, csrss.exe or wininit.exe . (Processes with these names existed for many years, it is very unlikely that Microdoft abandons them in the future while still allowing existing kernel mode modules to run.) Use ZwOpenProcess with POBJECT_ATTRIBUTES pointing to one of those process' names. If the call fails you are at boot time.
Also you may study Windows startup described in "Windows Internals" by Russinovich and Solomon. Most likely you will get a number of other ideas.
I've answered a similar question elsewhere on SO. The short version is that what you're asking is not normal driver behavior, so no API exists to support this. You can add in heuristics to tell you this, but they'll remain heuristics.
You can use IoGetBootDiskInformation to check if you are loaded post or, during boot. It will return STATUS_TOO_LATE if this API is called post reboot.

How do I turn off the fault tolerant heap?

I've recently started seeing this line in my Visual Studio 2005 output window when launching my application:
FTH: (7156): *** Fault tolerant heap shim applied to current process. This is usually due to previous crashes. ***
I've tried turning off the fault tolerant heap using the instructions here:
http://msdn.microsoft.com/en-us/library/dd744764(VS.85).aspx
I'm running Windows 7 64-bit edition, so I have made the changes to both the 32-bit and 64-bit registries, and run the "Rundll32.exe fthsvc.dll,FthSysprepSpecialize" command using both the 32-bit and 64-bit versions of Rundll32.exe.
However, after rebooting I am still getting the fault tolerant heap when trying to debug my application!
This is a real problem since it masks the bug I am trying to reproduce, and it also kills performance.
Does anyone have any other suggestions how to disable the fault tolerant heap?
To disable it for a single application
Go to the HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER versions of
Software\Microsoft\Windows
NT\CurrentVersion\AppCompatFlags\Layers\your_application.exe and
delete the FaultĀ­TolerantĀ­Heap entry.
From here (actually here)
Set this registry value to 0:
HKEY_LOCAL_MACHINE\Software\Microsoft\FTH\Enabled
You can add the name of your executable to the ExclusionList.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\FTH\ExclusionList
Works for me.
You can edit the application manifest to excluding your program from PCA
see also:How to reset Program Compatibility Assistant for testing
you can clear the list of applications tracked by FTH without stopping this service by following these steps:
Click the Start menu.
Right-click Computer and click Manage.
Click Event Viewer -> Applications and Services Logs -> Microsoft ->
Windows -> Fault-Tolerant-Heap.
View FTH Events.
you will find file named operational by right click and choose clear log,
then you can run you program again and warning message will disappear,
it worked with me without restarting operating system.
On Windows 10 the registry location is:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\FTH
You can remove you executable from the list in:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\FTH\State
or you can run this command from an elevated command prompt
Rundll32.exe fthsvc.dll,FthSysprepSpecialize
You may need to reboot your machine
"Rundll32.exe fthsvc.dll,FthSysprepSpecialize" looks to only clear the list of currently flagged applications. if your application still causes oddities, the FTH should still step in and take over.
as already mentioned:
Set this registry value to 0: HKEY_LOCAL_MACHINE\Software\Microsoft\FTH\Enabled
this should disable FTH for the whole system.
I had to rename the file as well because the registry entries associated with this key were empty of applicable data. I expect that they populate if you have a misbehaving application. But in my case I was debugging my own application within Visual Studio. So in that case, it was my process that was somehow loading the FTH whether the FTH Service was running or not. And in fact I had no applications listed that were previously tagged as misbehaving.
But I had to follow these instructions:
http://billroper.livejournal.com/960825.html
because it wouldn't let me rename the file until I took ownership and made sure I had full control.
I had similar issue when running a Unit test using (Microsoft::VisualStudio::CppUnitTestFramework).
Somehow I had violated some heap allocation, and next time I tried to debug I received the message : "Fault tolerant heap shim applied to current process. This is usually due to previous crashes. " and the debug environment froze.
To get it to work again, I had to remove test case, recompile and add it again and recompile, then I could set breakpoint and step into the test.
Also ran into this. Renaming/deleting AcXtrnal.dll inside Windows\AppPatch seems to work for me. I like how this Microsoft recommended action (which I did first) does nothing.

How to implement an automatic update detection model

Our software is not ever officially installed on Windows, and currently has an update model like this:
Connect to Internet
Click an Update Button
Connect to server-side program
Server-side program creates an md5 hash list of all the files in
the server program directory.
Client-side program creates an md5 hash list of all the files in
the client program directory.
A comparison is done to see if a file needs updated, removed from, or added
to the client's machine, and it does so until complete.
Well, I would like to move to a model I see used more frequently these days where the software is officially installed and something like this happens:
When an internet connection is detected, the program will automatically query the
server to see if there is an updated installation package.
If so, ask the user if they would like to download the new install.
If no, do nothing, if yes, download new install.
Programatically uninstall the old program and start the install of the
new package.
The part I need advice on is number 4 above. What is the best way to programmatically uninstall the old program and start the installation of the new program, while running the original program. I assume there must be some intermediary program that does all the work (shutting down the current program, running it's uninstaller, then starting up the new installer) Is there a better way? I just want to move to a model where we update in full installs and not just files - this will allow us to version our software easier and keep self-contained installations to revert to at any point.
Thanks for your advice!
EDIT: Related question - what's the easiest way to find the install UUID for a particular install?
The way I did it was to have a separate program (let's call it StartUp.exe) that checked for updates and then loaded the real software (let's call that Program.exe). StartUp.exe had the same icon as Program.exe and was the executable that was pointed to by the desktop shortcuts and menu items, using the same name as Program.exe.
So the sequence went something like this:
User double-clicks desktop shortcut or menu item that looks like Program.exe and is called the same name but is actually StartUp.exe
StartUp.exe runs and checks if there are any updates
If there are updates, it simply copies then across (we built a nice system with progress bars but you could simply copy the new files over the old files)
StartUp.exe then runs Program.exe
StartUp.exe then exits
This has the advantage that none of your program files are locked because the loader program is actually a different program. The user is none the wiser because they run a program that looks like and is called the same as the program they want to run and the end result is the program they want does run and is guaranteed to be the most up to date version.
Doing it with an update button would be more complex but we needed to force the most recent version of the program to be the one running (due to database differences between versions) so forcing update on startup worked for us.
I believe the way to do it these days is to use ClickOnce deployment but I've never tried that - it wasn't available when I wrote my system and this method was simple and worked well.

Identify a reboot

Is there any "Boot session ID" or (reliable) "Boot timestamp"?
For an installation I need to detect that a scheduled reboot took place indeed.
I guess I could do a dummy MoveFileEx() with MOVEFILE_DELAY_UNTIL_REBOOT, but i did hope for something easier.
(We have to install a 3rd party package that sometimes behaves erratically after an repair/update. In that state, accessing the device may even lock up the system)
(Windows XP, Vista, 7)
For things like this, WMI (Windows Management Instrumentation) is often a good starting place. I know you can get current uptime directly through it, which may allow you to determine if a machine recently rebooted.
Here is a blog post with some code samples as well:
http://blogs.technet.com/heyscriptingguy/archive/2004/09/07/how-can-i-tell-if-a-server-has-rebooted.aspx
Depending on your implementation language, you probably just want to pull out the query code from the vbscript.
Apparently Windows has the equivalent of "uptime". Here's more info: http://support.microsoft.com/kb/555737
As I understand it, this should tell you how long ago the system was booted. Will that information solve your problem?
You could search the System event log for event 6009 from the EventLog source - this is the first event recorded after each reboot.
I think the best answer has already been given here: Find out if computer rebooted since the last time my program ran?
That seems to be the simplest way. Use GlobalFindAtom() to see if it exists and create it, with GlobalAddAtom(), if it doesn't. It will persist beyond the execution of your program. If your application runs again, and sees that the atom exists, then then it isn't the first run since reboot.
If the computer is restarted, then the atom won't exist, indicating that this is the first run of your program since the reboot.

Resources