CreateFile in separate thread returns INVALID_HANDLE_VALUE in MFC app - multithreading

I have an MFC App which fires up a separate thread for downloading some files via cURL. At the start it downloads a text file with file sizes and last write times. Then it checks the files on disk and queues it for downloading if it has different values.. The problem is; the CreateFile call in the thread arbitrarily returns INVALID_HANDLE_VALUE. I always do CloseHandle() after a successful CreateFile(). The failing files are just random. Sometimes a file in the root dir, another time a file in a nested directory. The problem is not related to localization or directory/file names since sometimes all checks pass but sometimes don't. GetLastError() return 2 or 3 on occasion which are "File not found" / "Path not found" respectively.
When I put the function checking the file write times and size straight into the OnInitDialog() function, everything works. This smells like a multithreading issue but I double-checked everything from memory allocations to file handles.
The same code works in a console application also in a separate thread.
The platform is Win7 64bit.
Linking statically to the runtime and MFC.

in my case GetCurrentDirectory() returned the system32 path after some time so my code failed because of credentials. I fixed the issue by determining file paths manually (getting the exe path at the start and use it from there on...) . Make sure you are not trying to write to/read from a privileged location on disk. Check your paths.

Related

Flag to Create Missing Directories During fs.promises.writeFile

As I review these file system flags, I'm I correct in concluding that there is no flag you can pass to fs.promises.writeFile that will automatically create all missing directories leading up to a filename? If not, which flag does this?
I don't like solutions that check for the existence of the folders first before attempting writeFile, because after the folders are created that check happens every time you write to a file in that folder.
In my program, after the folders are created once, it should always be there, so it seems more efficient to only create the folders if there is an exception. However, I'm hoping there is a flag that avoids all this micro-management.
If a flag for auto-creating the folders doesn't exist for writeFile, then I'd like to attempt writeFile first, and then (only if there is an exception) create the folders recursively.
fs.promises.writeFile() does not automatically create the directory structure for you. That must exist first.
If you want to automatically create the path because you received an error indicative of a path problem, you can use fs.promises.mkdir() and pass the recursive flag.
And you could, of course, create your own wrapper function that calls fs.promises.writeFile() and if it gets whatever error you get when the path doesn't exist (you'd have to test to see exactly what that error is), then call fs.promises.mkdir() and then repeat the fs.promises.writeFile(). It could all be wrapped in your own utility function.

How do I diagnose this crash?

The Map file looks like:
0002:000442e4 00000118H .idata$2 DATA
0002:000443fc 00000014H .idata$3 DATA
0002:00044410 00000b7cH .idata$4 DATA
0002:00044f8c 0000512eH .idata$6 DATA
0002:0004a0ba 00000000H .edata DATA
The Crash info looks like:
Application Error : The instruction at "0x00458ae1" referenced memory at "0x00000074". The memory could not be "read".
I'm trying to get a stack dump on the next crash, but it seems to me this is a case where we trounced the stack, then did a return, which made us end up executing data.
I'm not entirely certain though because I read some articles like this: Under the Hood Article seems to indicate this is an area of imported method names
The data that an import library provides for an imported API is kept
in several sections whose names all begin with .idata (for instance,
.idata$4, .idata$5, and .idata$6). The .idata$5 section contains a
single DWORD that, when the executable loads, contains the address of
the imported function. The .idata$6 section (if present) contains the
name of the imported function. When loading the executable into
memory, the Win32 loader uses this string to call GetProcAddress on
the imported function effectively.
Without a stack backtrace I'm kind of stuck. Am I looking at this crash the wrong way?
Forget MAP files, better use PDB files. For this enable linker option /DEBUG - yes, even for Release builds. /DEBUG is linker option, _DEBUG is compiler option. Only _DEBUG controls the code, and any conditional compilation that source/headers have put against this.
Debug builds have optimizations disabled, _DEBUG macro enabled.
Release builds have optimizations enabled, _DEBUG macro disabled.
/DEBUG would just put debugging-information into the EXE/DLL, and wont affect anything else.
Coming back to problem, when crash occurs. Do NOT close the application when WER (Windows Error Reporting) says it crashed. Instead keep it there, goto Task Manager, goto Process tab, select that crashed/crashing process, and hit "Create Dump File". Dump file (full-dump) will be created in some local folder (the path will be shown by task-manager). You can now close the crashing application (the WER window).
Now copy this .DMP file into some safe location, preferably the folder having your original Release folder. Open it in Visual Studio or WinDbg. On VS, just hit F11/F10, and you will be shown call stack. If multiple threads are running (in your crashed application), launch "Threads" view, and see the only suspended thread, double click it and you'll find the crash location.
You must have correct PDBs along with all binaries, and absolutely same code to see Code, otherwise call stack wont be good.
To get more information about PDB and stuff, you can read this article.

Return value of c# exe with exec

i have a problem using inno setup. I'm installing an update with inno, and with the update.exe the user get a txtfile with a licencenumber. On his Unit this licencenumber readable by a dll function.
Before the installingprocess i have to compare these numbers. Only if this numbers are identical the user is trying to installing the update on the right machine with the right licence.
If i would put this check into an seperate exe, it would be easy to crack it by change the exe with one just doing nothing (no errorcode). So i want to split the checking into the seperated exe (where i check some other things like installed version number etc.) and the update.exe
In update exe, i want to read the txtfile inside the updatepackage - this is easy.
In check.exe i want to call the internal dll and get the licencenumber of the machine. I have to return this number as an int. C# allows me to do that.
But how can i get this number in innosetup?
I tried to take the errorcode for this (0=error - not right version etc, XXXXXXXXX = licencenumber of machine). But the errorcode is just 2 chars in inno. I get only 2 chars...
Saving the number in another file would'nt be a solution cause the user can crack it this way... Is it possible to get the number into inno without giving the user the chance to manilpulate??
If you move the code into a DLL (either COM or a plain stdcall DLL) then it can be used by Inno and pass extra data between them including full strings, etc.

VC++ - Asynchronous Thread

I am working on VC++ project, in that my application process a file from input path and generates 3 output "*.DAT" files in the destination path. I will FTP these DAT file to the destination server. After FTP, I need to delete only two output .DAT files the folder. I am able to delete those files, because there one Asynchronous thread running behind the process. Since the thread is running, while deleting it says, "Cannot delete, the file is used by another person".
I need to stop that thread and delete the files. Multiple files can also be taken from the input path to process.
Please help me in resolving this issue. Its very high priority issue for me. Please help me ASAP.
I don't think this is a threading issue. Instead I think your problem is that Windows won't let you delete a file that still has open handles referencing it. Make sure that you call CloseHandle on handles to the file that you want to delete first. Also ensure that whatever mechanism you are using to perform the FTP transfer doesn't have any handles open to the file you want to delete.
I don't think that forcing the background thread down will solve your problem. You can't delete the files because you're holding an open handle to those files. You must close the handle first. Create an event object and share it between your main thread and the background thread. When the background thread is done sending the files through FTP, it should set this event. Have your main thread wait on the event before deleting the files.
Background Thread:
SendFiles();
ReleaseResources(); // (might be necessary, depending on your design)
SetEvent( hFilesSentEvent );
Main Thread:
WaitForSingleObject( hFilesSentEvent );
DeleteFiles();

Calling dll function but file cannot be written when application is open

I have a function in a dll that involves reading and writing a file.
I am calling the dll function in a test application but the file could not be written when the application is still open. I always need to close the test application first before the file could be successfully written.
What do I have to do to fix this?
I am calling the function repeatedly in a loop. When there are multiple items needed to to processed using that function, the application crashes. It works fine when only one item is processed. What can I do?
Note: my dll is actually an .exe that I converted to dll.
My guess would be the file is already open. Is your code doing a file open and then leaving the file open?
Check the code to make sure there is a matching file close for every file open.
Open the file with the right sharing permissions? What API are you using to open the file?
I would recommend using a different file name when you call the function from your test code. If possible, modify the dll to accept a filename.
If not, make sure you open the file in shared mode.

Resources