What does the "WOW64" value in the registry of the windows serices do, which are located in:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
I attached an screenshot.
Here is my problem: I created a service with
<myserviceexe> /install
It looks like in the screenshot. The Serviceexecutable is compiled in 32bit and running fine.
After that i manually created a 2nd service with
sc create myservice binpath=C:\myservice.exe start=auto
The 2nd service is also compiled in 32 bit (but a completly different service than the 1st one) and running fine when created with the 2nd command. However, when creating the 2nd service, there is no WOW64 entry in the registry. If I add this entry manually (just out of curiosity for testing), the service throws an very, very, very weird error "ERROR_MORE_DATA 234: There is more data" (whatever this means) (https://learn.microsoft.com/de-de/windows/win32/debug/system-error-codes--0-499-)
Can someone explain what the WOW64 entry is doing? I find absolutly zero information online. I know what WOW64 usually means: The binary is a 32 bit binary and runs in an 32 bit environment. But what does this have to do with the services and why does my 2nd service not run when the WOW64 entry is created in the registry, although it is an 32bit binary?
i looked what happened when starting the 2nd service with process monitor from ms-sysinternals and noticed a buffer overflow when the program loaded the WOW64 regkey, which I created manually. I then noticed i created a QWORD instead of a DWORD in the registry xD
When using an DWORD (as you should) the 2nd services also just runs fine.
Related
Update: It turned out that there was something with installing Delphi 10.4 CE that broke my app (thanks, DelphiCoder!); specifically, it was something in the Windows Registry that was broken. After using ProcessMonitor to ensure no Delphi 10.4 (aka 21.0) was being invoked, I ended up cleaning out the registry of all 10.4 references, rebuilding completely (not clear if this was needed or not), and lo and behold, it works again! I'm adding this update in case someone in a similar situation finds this question - remember to back up your registry first and be careful!
Original Post: I created several DLLs with Matlab Compiler 10 years ago, with C wrappers, to make them available with Delphi. Once I got them working, they always worked - until today! The code in the C wrapper initialization function in question is in the code box below; the "Could not initialize library" is printed to the console when I run my Delphi app.
mclmcrInitialize();
if (!mclInitializeApplication(NULL, 0)) {
fprintf(stderr, "Could not initialize application\n");
}
if (!libMyDllInitialize()) {
fprintf(stderr, "Could not initialize library\n");
}
The problem is that this has never happened before, over all the probably 10 years since we first wrote these! My machine has the correct version of the 32-bit 2021a MCR installed, as it has for several years; I've installed this on numerous machines from Windows XP up to Windows 10, The DLLs were last built 5 - 7 years ago; anyway, I don't have access to the Matlab compiler anymore. The only thing that has changed is my app, but not anywhere near where this DLL initialization code is called; also, when the problem first happened, my app was working, then didn't -without any changes. Finally, I went back a few days and rebuilt my app, and it still fails.
So I am really stuck, and need some advanced help in debugging DLL startup issues on Windows. I tried looking in the Windows Event Logger, but nothing appears to show up there. Logs to check? A setting in the Registry that somehow got hosed? Wrong phase of the moon? How does one debug loading/initializing a formerly working DLL when forced to treat it as a black box? Help!
How does one debug loading/initializing a formerly working DLL [...]?
I think there is no definitive answer to your question.
This is how we have gone about debugging the loading/initializing of DLLs and applications and may help you:
We regularly work with systems where we have no source code for the DLLs (and often we don't have any source code for the applications either). We experience DLL conflicts quite regularly. When testing why applications don't start as expected we have found the use of Sysinternal's Process Monitor by Mark Russinovich invaluable.
This will show you system level activity. You can filter for your process and then you will see all file, registry, thread and network activity (although thread and network are quite limited). If the DLL has dependencies then the system tries to find those and so you will be able to discover all dependent DLLs and COM interfaces (by seeing the registry lookups for that interface) that it's looking for. Process Monitor will show if the resource is not found or if access is denied.
Slightly more difficult to discover is if one of the dependencies exists but the export table has changed (so the functions have different signatures or export ordinals). There are ways to check that (by looking at the export and import tables) but generally (if you have access to a working environment) it's enough to check the filesize, timestamp (and the VERSIONINFO resource if there is one) between DLLs.
I think that I've pinpointed my issue, and it looks like it is environmental.
Basically one of the apps that is doing a lot of data computation (ML) is having issue with accessing that data in a high load scenario.
I have .net core 3.0 app using Worker to connect to MySQL and retrieve data (~ 4000-5000 queries per second for ~ 60 seconds).
When I am running it locally via dotnet run it seems to be working fine (never saw an error). However when I try to run it via docker (microsoft 3.101 image or bionic 3.101 sdk/runtime) or directly from Ubuntu with 3.1 sdk, I will start getting number of weird random errors (i.e. table doesn't exist, operation cancelled, often app was freezing without an error (the thread on Hangfire, when running without it would stop acking to RabbitMQ etc. so weird state)).
Now I am running it without Hangfire, with specified threads that are started via worker.
Weird thing is that all errors will be having paths
".... in C:\projects\mysqlconnector\src\MySqlConnector\...\xxxxx.cs"
However this is happening on Linux / Docker linux image, so not sure how it can even know about existence of C:...
It is totally killing me for last 72 hours as this is a big new feature that is using ML to process huge amount of data on hourly basis, and basically MySQL is not working with it in either environment beside dev (local machine with windows).
Caused by a corrupted library built from a source. Developer somehow managed to use .net core / .net framework as a target corrupting whole project. However in Windows it worked fine.
There was also another similar library used by mistake in one of source libraries... That is why it worked in most cases...
Solved by removing corrupted library, using different build that would be free of corrupted target.
I am using Delphi 5. I originally had problems copying a file from a network mapped drive. If I use the UNC path I can copy the file. The problem is I wont always know the UNC path. I am using windows 10, 64 bit. Is there a solution that would allow me to obtain the UNC path? Every time I use the ExpandUNCFileName function it returns the path N:\tmp\file1.mdb instead of \hermes\apps\tmp\file1.mdb. If I run the code on XP or Windows 7 it returns the UNC path correctly but when I run it on Windows 10 it fails and gives me the path with the drive letter.
What I am trying to do is run an install program which updates a database file. For it to work I need to copy the database file locally. Now the problem happens when I first start the update program exe, my windows 10 forces the program into run administrator. As soon as I run the exe it pulls up an administrator login. It only does this on windows 10. With windows 7, XP it does not ask or force it to run as administrator.
Please help if you can, thanks.
ExpandUNCFileName works correctly. If you call that function from a context which has the drive letter mapped, then it will return the desired UNC name.
The problem therefore must be that when you call the function the drive is not mapped. Common reason for that would be that your code was executing in a service, or under a user account that does not map the drive, but there are other reasons.
Exactly how to solve your problem is not clear from here. You might solve it by making sure that the drive letter is always mapped. However, this is a potentially brittle approach, as you are discovering.
Perhaps a more reliable approach would be to operate exclusively with UNC names. This after all is the reason for their existence. So, when the user provides you a path to a network directory or file, convert it at that point to a UNC name. From that point on use that UNC name.
If you don't want your program to be elevated then you need to either give it an application manifest, or change its name. Executables without application manifests, and with names like update or patch, are elevated by UAC aware versions of Windows. UAC was introduced 12 years ago, it is perhaps time for you to get up to speed with the implications for developers. Not least because your old Delphi 5 development environment predates UAC, and therefore will not generate and link a manifest for you.
We have a Delphi program whose task is like a service program. It watches a particular folder for a certain period, and it works great on Windows XP and 2003, but on Windows 2008r2 64bit, when it wants to create an automatic folder, it will show this message:
The ... folder does not exist. The file may have been moved or deleted.
This message causes the program to halt, which is not good; it should not be interrupted.
What can I do about this?
P.S.: I really don't have any idea whether to post my problem in Stack Overflow or Server Fault, so I've guessed it should be here.
It's likely the VirtualStore, if you're trying to store beneath Program Files (either one). See my writeup:
http://www.clipboardextender.com/off-topic/vista-program-files-hide-and-seek
You've left out the ... folder name. While that's understandable, it wouldn't happen to have anything to do with program files (which on x64 will be split in 2 directories) would it?
Windows Server 2008 is able to use 'virtual' file pathes. That means: 'what you see is not what you get'. The Windows Explorer just shows you the 'display' name. Check the file path with cmd.exe, if the path you are trying to use does realy exist.
The reason is of cause the File Virtualization (see for example http://msdn.microsoft.com/en-us/library/bb756960.aspx and http://technet.microsoft.com/en-us/magazine/2007.06.uac.aspx).
Because we on stackoverflow.com and not on serverfault.com I want add to all other answers that you can use Wow64DisableWow64FsRedirection, Wow64RevertWow64FsRedirection and Wow64EnableWow64FsRedirection functions (see http://msdn.microsoft.com/en-us/library/aa365743.aspx) to control the File Virtualization in your program. An example of the usage of this functions in C# you can find here http://www.pinvoke.net/default.aspx/kernel32.wow64disablewow64fsredirection.
You'll need to tell us the exact path and how do you go about constructing it. It can be as simple as the app not using env variable expansion but assuming that user's folders are where they were before.
Path virtualization (there are 2 kids actually) that people mentioned will hit you only if your app is trying to mess with system folders.
More puzzling problem will hit you if you are not expanding env vars like APPDATA, LOCALAPPDATA etc. and not expecting that there's more of them on Win7 and 2k8. Not only that default paths of user's files changed but some of them can also be on network shares - for the same user. So if you were running based on expectation that all user's stuff will be at definite paths under say %USERPROFILE% you can get hit by several surprises. Also notice %ProgramData% .
Fastest way to find out - open cmd.exe, run set and if you see some paths that you are constructing in alternative ways, take notice that you need to start expanding env vars for them. Then open cmd.exe as a 32-bit app and check set again. You can also pick them up via Process Explorer from some running 32-bit or 64-bit app.
Switching your app to 64-bit build will resolve most of virtualization issues but not the env var expansion. Also if your app is touching system folders you need to request elevated run from the code or even better make the manifest and declare it there. Then OS will yell at user up front if his UAC is on and your app will avoid that 2nd virtualization. BTW, virtualization is controllable via group policies so it might be present on some boxes and missing on others.
Does the same technique which FastMM4 for Delphi provides to report memory leaks to a detailed file work if the application runs as service? Of course the best practice would be to write unit tests and a simple standalone application first, and find the leaks there, outside the service environment.
As Lars Truijens notes, writing to a log file requires file system privileges. The default Local System account (i.e. when you do not set an account explicitly or logon in your code) has full access to the local file system but has no default network access.
FWIW - I typically develop my services as regular Windows apps until the main part of the logic is up and running and stable. Using a library like SvCom allows you to run your services as a regular desktop application or as a service without any code changes.
Yes, provided the account used to running the service has enough rights to write the log file.
I am having the same challenge at the moment. I tried this, but it does not work, at least so far for me. There are sufficient rights for the account, since the service can write his own proprietary logfile. I have switched on FullDebugMode and added the dll, I have switched on LogMemoryLeakDetailToFile, both via the IDE options. In the code I see that the right areas are seen by the compiler, when I provoke an error for example, the compiler reports it. Also I cannot debug the FastMM code. If I put a breakpoint it is ignored. I have searched all my local hard disks where that report might be gone to, it is not to be found. I start and stop the service from 'Administration-Services', all goes well, it starts up, but no report. If I do the same with a normal executable, all goes well. I am using FastMM478, and Delphi2007.
Marc
Ok I found out another reason why sometimes you cannot see any output, logfile or messagebox......
If you do not make any error, it does not create any output.
So to test if FASTMM478 works deliberately make an error in your program like:
//Create and to NOT destroy
testToMakeError := TStringList.Create;
for I := 0 to 100 do
testToMakeError.Add('foobar');
I just presumed I would have made some error somewhere and spend a day trying to find out why the program did not gave me any feedback.
Marc
Do the instructions as described in the readme file for FastMM
Enable {.$define NoMessageBoxes} in FastMM4Options.inc File
Disable {$define RequireDebuggerPresenceForLeakReporting} in FastMM4Options.inc File
Install/Start Service and after stopping it you will get MyApp_MemoryManager_EventLog File in output folder.