File I/O not being executed in windows C++ service - c++

I wrote a simple Windows C++ service (Visual Studio 2012), which starts, listens on a port and also prints log messages to a file.
This is the startup code:
#include <stdlib.h>
#include "MyHeader.h"
int main()
{
if(!InitAndStartService())
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
Within InitAndStartService, I call StartServiceCtrlDispatcher and open my logging file writing a couple of messages to it.
The problem I'm facing is that the file is never created. The file I/O logic is written using CreateFile and WriteFile.
I even tried putting in the following code snippet in the main right before the if condition:
FILE *file = fopen("temp.txt", "w");
char *str = "hi";
fwrite((void *)str, 1, strlen(str), file);
fclose(file);
But the file is still not created. I had also put in a check such that if the file handle returned from fopen was NULL, I'd directly exit without going into InitAndStartService so that the SCM would give an error. But it turns out that the file handle isn't null.
The service does start and stop properly, but I don't see the port being open using netstat while it is running. The service is running as Local System, and has the required permissions to write to the folder.
What could be the reasons for this behaviour, and how can I dig further into this ?

Related

C++: Problems of file write using FILE Library when file beat process is running

I have a code for file write using FILE Library, and usually works, but I found a case where doesn't work: When the code runs concurrently with filebeat process.
I don't know this cause of the problem because my c++ project does not support debugging mode.
I am participating in an open source project developed by someone else and i am not familiar with this project yet.
This is my c++ code:
FILE *fptr;
fptr = fopen("log_path.c_str()", "w");
if (fptr == NULL)
{
printf("Error!");
exit(1);
}
fprintf(fptr, "%s", log.c_str());
fclose(fptr);
Is there a any other good way to save log files?
Please give me some advice.
Your code have broken-pipe exception when you try to write a file.
This exception occurs when a c++ code try to write a log file while the filebeat software is reading the log file.
So, I recommend using this C++ code:
#include <fstream>
#include <iostream>
logFilePath = "this is path string of log file";
log = "this is log string";
ofstream output(logFilePath, ios::app);
output << log << endl;
output.close();
This code that used the offstream library will be solve the broken pipe exception.
If you use this c++ code, it is able to use string type for file write process, so it's not necessary to type convert via c_str().
I checked that this code able to used with File beat 7.10.0.
Thank you.

Stopping an exe file from being run C++

I am creating an application to manage other applications or exe files on a user's computer, and stop them from accessing them at certain times (like ColdTurkey's application blocking feature).
The way I am trying to do this has not been working so far - I attempted to do this by opening the file dwShareMode set to 0 using the CreateFile function. This seems to work for files such as text files and does not allow the file to be opened, however this is not the case if I try and do this same approach on exe files, and the user is free to open the file.
I assume that exe files are not 'read' in the same way by Windows as a text file is read by notepad and that that means setting the dwShareMode to 0 does not affect it being opened, however I do not know what the difference between these are. Any help would be appreciated.
Code here (for the text file):
#include <windows.h>
#include <string>
#include <iostream>
using namespace std;
int main()
{
HANDLE test;
test = CreateFile("test.txt",
GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
cout << "press enter to stop blocking application: ";
string b;
getline(cin, b);
cout << endl;
CloseHandle(test);
return 0;
}
Your code works fine for me to block execution of the file. You do need to specify OPEN_EXISTING instead of CREATE_NEW (because you're not trying to create a new file here).
Not a windows expert -- I'm used to Unix/Linux and use the Cygwin package so I can program "in Unix" on my Windows desktop -- but it looks to me like you need to set the lpSecurityAttributes parameter, the one that comes after dwShareMode.
I think the following page might be helpful:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa364399(v=vs.85).aspx

Trying to use URLRequestInfo::SetStreamToFile and URLResponseInfo::GetBodyAsFileRef

I am working on an NaCl plugin for Chrome, and trying to download a URL resource file locally, into the temporary cache of Chrome, but without success.
Here is how I proceed:
// I indicate that I want the resource to be downloaded to a file
m_URLRequestInfo.SetStreamToFile( true );
// I open the request:
m_URLLoader.Open( m_URLRequestInfo, m_CCFactory.NewCallback( &MyClass::OnOpen ) );
...
// My callback (OnOpen) is eventually called.
// I then check to make sure the status code is 200 using this call:
m_URLLoader.GetResponseInfo().GetStatusCode()
// Then I ask to download the whole file:
m_URLLoader.FinishStreamingToFile( m_CCFactory.NewOptionalCallback( &MyClass::OnFileDownloaded ) );
...
// My other callback (OnFileDownloaded) gets eventually called,
// and again the status code is 200.
// Then I query the FileRef using this call:
pp::FileRef l_FileRef = m_URLLoader.GetResponseInfo().GetBodyAsFileRef();
The returned pp::FileRef seems to be fine, but pp::FileRef::GetFileSystemType() returns PP_FILESYSTEMTYPE_EXTERNAL, and then the call to pp::FileRef::GetPath() fails (it returns an UNDEFINED pp::Var).
So from this point, I am lost. I don't know what else I should do to get a valid pp::FileRef that points to a local file in the browser's cache. My final goal is to open this local file (an image file in my case) using a standard system file IO like fopen().
Thanks for any light !
Is there a reason you can't use the nacl_io library instead? With it you can write something like this:
#include <stdio.h>
#include <sys/mount.h>
// Mount an HTTP filesystem that reads files from "http://example.com/path/...".
mount("http://example.com/path/", "/mnt/http", "httpfs", 0, "");
// Performs a URL Request of "http://example.com/path/my_image.png".
FILE* file = fopen("/mnt/http/my_image.png", "r");
...
Take a look a the nacl_io demo in the SDK. It is located at $NACL_SDK_ROOT/examples/demo/nacl_io.
After reading more thoroughly the documentation and running more tests, I finally figured out what I was doing wrong.
When we call pp::URLLoader::FinishStreamingToFile, then the file is downloaded in Browser's cache, but it cannot be opened/read using regular stdio services like fopen, fread etc. We need to use the pp::FileIO class services to open the obtained pp::FileRef and read the content of the file.
So here is what I did to successfully load and read a file that was downloaded for me by the Browser. Basically, I continued to use the C++ PPAPI services.
(1) upon callback from m_URLLoader->FinishStreamingToFile, we then call m_FileIO->Open to open the downloaded file using the obtained FileRef;
(2) upon callback from m_FileIO->Open, we then call m_FileIO->Query to obtain the size of the downloaded file (and some other file attributes);
(3) upon callback from pp::FileIO::Query, we then check the file attribute type (e.g. not a folder), allocate a memory buffer large enough to hold the whole file content, and start to call pp::FileIO::Read to obtain the file's content;
(4) upon callback from pp::FileIO::Read, if the obtained nResult argument is 0, then we reached the EOF and we finished reading the file content into our memory buffer; if the obtained nResult > 0, then it indicates the number of successfully read bytes, and we call m_FileIO->Read again to continue reading bytes, and storing them at a different offset location into our memory buffer; if the obtained nResult < 0 then an error occurred and we must terminate the reading process.
Many steps, and many callbacks to manage, but in the end this works smoothly.

.exe file throws exception when opening file

I'm trying to write a CGI script in c++ which prints the reverse network path (using
traceroute) from the web server to the IP address of the client invoking the CGI script.
When I run the program in Visual Studio, it works fine(creates the process, prints the result into "C:/result.out" file, opens the file, prints each line from file, closes file) BUT after compiling and trying to run just its .exe file, it throws an exception. What could I do to make the .exe work properly ?
Just as a note, I'm using Windows XP and Visual C++ 2008
Here`s the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <process.h>
#include <conio.h>
int main()
{
char *line, *command, *userIp;
printf("Content-Type:text/html\n\n");
printf("<html><head></head><br/>");
printf("<body><br/>");
line = (char*)malloc(255*sizeof(char));
command = (char*)malloc(10*sizeof(char));
userIp = (char*)malloc(30*sizeof(char));
//userIp = getenv("REMOTE_ADDR"); // use a default IP until program works
strcpy(command,"tracert ");
strcpy(userIp,"74.125.87.104");
strcat(command,userIp);
strcat(command," > C:/result.out");
// create command "tracert 74.125.87.104 > C:/result.out"
printf("%s",command);
system(command);
FILE *f;
f = fopen("C:/result.out","r"); // open C:/result.out and read line - by - line
strcpy(line,"");
while(!feof(f)){
fgets(line,255,f);
printf("%s\n",line);
}
fclose(f);
printf("<br/>Test running OK<br/>");
printf("</body></html>");
getch();
return 0;
}
Most likely your web server (sanely) doesn't have permission to write to c:\. Either use a proper location for temporary files, or have tracert stream the results back to the executable so you can capture them.
Well the following two lines cause buffer over-runs
strcat(command,userIp);
strcat(command," > C:/result.out");
So this is likely the result of a crash.
Please do not use the term "Exception" unless an exception is being thrown, and since you are writing C code that is unlikely. So it is not an exception.
Rather than running a command using system() and piping the result to a file use the popen() command this will run a command and pipe the output to a stream that you can read just like a file (but without the security implications of writing to the file system).
FILE *f;
f = popen(command,"r"); // run the command. The std out goes to the FILE stream
^^^^^^
strcpy(line,"");
while(!feof(f)){
fgets(line,255,f);
printf("%s\n",line);
}
fclose(f);

Sharing violation on file which really should be closed

I have an application that modifies an XML file by:
(a) opening it,
(b) creating a temporary file and writing a modified version to it,
(c) closing both files, and
(d) replacing the original file with the temporary file.
When I test it on my laptop running Vista, everything works just as it should. On an embedded PC running XP Professional SP2 with a flash drive instead of a hard disk (which may or may not be relevant), it fails at step (d) with an access violation (error code 5).
If I insert code between steps (c) and (d) to verify that the files are closed, it confirms that they are; if I put in code between steps (c) and (d) to try to delete the original file, it fails with a sharing violation (code 32). If I pause the program at this point and try to delete the file from the GUI, it fails with a sharing violation. If I use systinternals "Process Explorer" at this point, it shows the application still has a handle to the file.
Here is some of the code:
// Open the file which is to be updated:
_wfopen_s(&inStream, m_fileName, L"r, ccs=UTF-8");
// Obtain a suitable temporary filename from the operating system:
TCHAR lpTempPathBuffer[MAX_PATH]; // Buffer to hold temporary file path
TCHAR szTempFileName[MAX_PATH]; // Buffer to hold temporary file name
GetTempPath(MAX_PATH, lpTempPathBuffer);
GetTempFileName(lpTempPathBuffer,
TEXT("TMP"),
0,
szTempFileName);
// Now open a temporary file to hold the updates:
errno_t err = _wfopen_s(&outStream, szTempFileName, L"w, ccs=UTF-8");
if (err == 0)
printf ("Temporary file opened successfully\r\n");
else
printf ("Temporary file not opened; error code %d\r\n", err);
Then the gubbins that modifies the file, and then ...
// Finally, we must close both files and copy the temporary file to
// overwrite the original input file:
int closerr = fclose(inStream);
if (closerr == 0)
printf("Original file closed properly\r\n");
else
printf("Original file not closed properly\r\n");
closerr = fclose(outStream);
if (closerr == 0)
printf("Temp file closed properly\r\n");
else
printf("Temp file not closed properly\r\n");
int numclosed = _fcloseall();
printf("Number of files closed = %d\r\n", numclosed);
// Should be zero, as we've already closed everything manually
if (!DeleteFile(m_fileName))
{
int err = GetLastError();
printf ("Delete file failed, error code was %d\r\n", err);
}
else
printf ("Delete file succeeded\r\n");
if (!MoveFileEx(szTempFileName, m_fileName,
MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED | MOVEFILE_WRITE_THROUGH))
{
int err = GetLastError();
printf ("Move file failed, error code was %d\r\n", err);
}
else
printf ("Move file succeeded\r\n");
The output log shows:
"Temporary file opened successfully
Original file closed properly
Temp file closed properly
Number of files closed = 0
Delete file failed, error code was 32
Move file failed, error code was 5"
This makes no sense... Why am I getting a sharing violation on a file which the operating system insists is closed? And is there a reason why this works in Vista but not in XP?
Many thanks for any advice,
Stephen.
One thing to keep in mind with Flash media is that the access times can be much longer, and the file actions are frequently handled asynchronously. Windows may be returning to your code saying that the file is closed before the device driver has actually released it. You go to delete it, and it's really still in use, according to the device driver.
I'd suggest putting a delay in there for testing purposes (say 5-10 seconds), after the file closes and before you try to delete the file. If it works, then what you need to do is to loop on the delete action a couple of times (with a short delay in the loop) and exit the loop when the delete succeeds, or you hit a max # of attempts (say 4-5).
If you still have the same problem, even with a 30 second delay, then the problem probably lies somewhere else.
It seems to be a problem with file permissions. After trying various other things which didn't work, I decided to try opening the file with read/write permissions (i.e with the "r+" attribute rather than "r"), and then overwriting the original file contents with the contents of the temporary file. This time, the "_wfopen_s" command itself failed with error code 13 ("Permission denied"), indicating that the operating system was clearly not willing to let the program tamper with this file under any circumstances.
So I guess I need to frame the question slightly differently: why, when
(a) my application works perfectly as-is in Vista, and
(b) I can freely edit the file when I am using the GUI in XP, and all the file permissions look to be set correctly, and
(c) the program that is trying to modify the file is running from a session that is 'logged in' as the file owner
...can the file not be modified by the program?
Is this a curiosity of XP, or of the fact that it's running on an embedded computer with flash memory? If it were the latter, I'd expect there to be problems when creating brand new temporary files as well, but this seems to work just fine.
I'd once again value any suggestions.
Stephen