I am currently working on a project where I need to read windows events .
I am using OpenEventLog() and ReadEventLog() from Win API. I can read the events from system using the typename of the event.
But I need to specify the file name or file path of the .evtx file that I have saved from the EventViewer.I tried the below code,
HANDLE logHandle = OpenEventLog(NULL, "C:\\Users\\MyAccount\\Documents\\myevents.evtx");
DWORD status = GetLastError();
if(logHandle == NULL){
cerr<<"NO HANDLE GENERATED!!!"<<endl;
}else if(status == ERROR_INVALID_HANDLE){
cerr<<"INVALID HANDLE!!!"<<endl;
}else if(status!=0){
cout<<"OPENEVENTLOG ERROR STATUS::>"<<status<<endl;
}
But it does not find the specified file and switches over to default Application Events. Can anyone please tell me what the problem could be? or if there is anything to be changed in the code?
PS: I even tried placing the file in project folder and specifying just the filename(myevents.evtx) , but still doesn't work.I also tried reading the evtx directly as shown in "Reading .evt/.evtx files directly" , but later I found this can't be done. Apparently there is no way to read them directly without win API or without writing a whole bunch of parser code.
Thanks in advance.
Well, it turns out OpenEventLog() is not meant for opening saved .evtx files.
I should've been using OpenBackupEventLog() for that.
Related
I had the following code which got executed every two
minutes all day long:
int sucessfully_deleted = DeleteFile(dest_filename);
if (!sucessfully_deleted)
{
// this never happens
}
rename(source_filename,dest_filename);
Once every several hours the rename() would fail with errno=13 (EACCES). The files involved were all sitting on a DropBox directory and I had a hunch that DropBox could be the cause. I figured that it might just be possible that the DeleteFile() function may return with a non-zero successfully_deleted but actually DropBox could still be busy doing some stuff in relation to the deletion that prevented rename() from succeeding. What I did next was to change rename() to my_rename() which would attempt a rename() and upon any failure would Sleep() for one second and try a second time. Sure enough that has worked perfectly ever since. What's more, I get a diagnostic message displaying first-attempt-failures every several hours. It has never failed on the second attempt.
So you could say that the problem is entirely solved... but I would like to understand what might be going on so as to better defend myself against any related DropBox issues in the future...
Really I would like to have a new super_delete() function which does not return until the file is properly deleted and finished with in all respects.
under windows request to delete file really never delete file just. it mark it FCB (File Control Block) with special flag (FCB_STATE_DELETE_ON_CLOSE). real deletion will be only when the last file handle will be closed.
The DeleteFile function marks a file for deletion on close. Therefore,
the file deletion does not occur until the last handle to the file is
closed. Subsequent calls to CreateFile to open the file fail with
ERROR_ACCESS_DENIED.
also if exist section ( memory-mapped file ) open on file - file even can not be marked for delete. api call fail with STATUS_CANNOT_DELETE. so in general impossible always delete file.
in case exist another open handles for file (but not section !) begin from windows 10 rs1 exist new functional for delete - FileDispositionInformationEx with FILE_DISPOSITION_POSIX_SEMANTICS. in this case:
Normally a file marked for deletion is not actually deleted until all
open handles for the file have been closed and the link count for the
file is zero. When marking a file for deletion using
FILE_DISPOSITION_POSIX_SEMANTICS, the link gets removed from the visible namespace as soon as the POSIX delete handle has been closed,
but the file’s data streams remain accessible by other existing
handles until the last handle has been closed.
ULONG DeletePosix(PCWSTR lpFileName)
{
HANDLE hFile = CreateFileW(lpFileName, DELETE, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OPEN_REPARSE_POINT, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
static FILE_DISPOSITION_INFO_EX fdi = { FILE_DISPOSITION_DELETE| FILE_DISPOSITION_POSIX_SEMANTICS };
ULONG dwError = SetFileInformationByHandle(hFile, FileDispositionInfoEx, &fdi, sizeof(fdi))
? NOERROR : GetLastError();
// win10 rs1: file removed from parent folder here
CloseHandle(hFile);
return dwError;
}
Update
Sorry i didn't get the question correctly the first time. I thought DeleteFile returned error 13.
Now I understand that DeleteFile succeeds but rename fails immediatlely after.
It could be just a sync issue with the filesystem. After calling DeleteFile the file will be deleted when the OS commits the changes to the filesystem. That may not appen immediately.
If you need to perform multiple operations to the same path, you should have a look at transactions https://learn.microsoft.com/it-it/windows/desktop/api/winbase/nf-winbase-deletefiletransacteda.
-- OLD ANSWER --
That is correct. If the another application handles to that file, DeleteFile will fail.
Citing MSDN docs https://learn.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-deletefile :
The DeleteFile function fails if an application attempts to delete a file that has other handles open for normal I/O or as a memory-mapped file (FILE_SHARE_DELETE must have been specified when other handles were opened).
This applies to dropbox, the antivirus, or in general, any other application that may open those files.
Dropbox may open the file to compute its hash (to look for changes) at any moment. Same goes with the antivirus.
I have been scratching my head around this problem for a while, and I couldn't find any answer through surfing the web either.
The problem is that I call system("csvtojson someFile.csv 1> someOtherFile.json") inside my program to produce a JSON file. After this line I want to open, read, and process the JSON file. Although, I can see that the file is created, but fopen() returns NULL.
I read that system() is synchronized so I think the rest of my program will not get executed until the system call is finished, and so the file will be created.
I suspect the problem is somehow related to redirecting the output stream using "1>"; not sure, though.
Any help or hint will be much appreciated.
Thanks! :)
P.S. I don't want to use a library to convert csv to JSON, and I can't perform the conversion outside the program because there are tons of very large csv files and the only way for me is to convert each to a JSON file inside the program, run my algorithm, and move to the next csv file ( converting it to JSON and saving it in the very same JSON file). So in total I have only one JSON file, being like a buffer for my csv files. Having said that, if anyone has a better design approach that can be implemented quickly, that would be also great.
UPDATE : Actual code that exhibits the problem, copied from the OP's answer:
int main(){
system("csvtojson Test_Trace.csv 1> ~/Traces/Test_Trace.json");
FILE* traceFile = fopen("~/Traces/Test_Trace.json", "r");
if(traceFile == NULL)
perror("Error in Openning the trace file");
else
cout << "Successfull openning of the trace file!" << endl;
return 0;
}
Thank you guys for your answers. I had to be more detailed in my question as the problem seemed to be somewhere that wasn't clear from my question.
I figured out what was the problem, and would like to share it here (not a super interesting finding, but worth mentioning).
I wrote a simple program to find the problem:
int main(){
system("csvtojson Test_Trace.csv 1> ~/Traces/Test_Trace.json");
FILE* traceFile = fopen("~/Traces/Test_Trace.json", "r");
if(traceFile == NULL)
perror("Error in Openning the trace file");
else
cout << "Successfull openning of the trace file!" << endl;
return 0;
}
If you run this program you will get the error message No such file or directory, but if you replace the address string with the absolute location, i.e., /home/USER_ID/Traces/Test_Trace.json, in both system(...) and fopen(...) calls, your code will work fine. Interestingly, myself suspected that this could be the problem and I changed just the one for system(...) but still it wasn't working (though the file was being created in the location that was passed to fopen(...)).
EDIT: Thanks to #Peter's comment, this problem was because system() call takes care of ~, but fopen() does not and need an absolute path. So there is really no need to have both functions been given the absolute path.
Anyhow,
Thanks Again. :)
Perhaps the reason for this is because the system command hasn't finished executing by the time your program continues to the next instructions where it tries to read from the file that hasn't been created yet.
Although, this isn't the best way, putting in a short pause might make the difference, or at least let you know if that is the issue.
I am attempting to create an addon for Node.js that (among other things) writes content to a file inside my C++ class using ofstream.
std::ofstream license_file;
std::string fileContent(*NanAsciiString(args[0]));
license_file.open(PATH);
//file doesn't yet exist, so create it
if(!license_file) {
printf("ERROR: %s (%s)\n", strerror(errno), PATH);
}
license_file << fileContent;
license_file.close();
This works fine if PATH is set to the same directory as my Node.js code (e.g. ./license.txt).
However, ofstream fails to open/create the file in question if it is located anywhere else. For example, using ~/license.txt does not work (note: I'm running OSX).
The error reported is always No such file or directory -- even after I physically create ~/license.txt.
Any ideas why this works in one directory but not others? If it were a permissions issue I would expect a different error message.
For the record, I've seen about 20 other SO questions about "ofstream fails to create file" but passing additional flags into open() has no effect. I have a feeling this is somehow related to running inside Node/V8.
I think the issue is that you need to find out the user directory in a different way than using ~.
i am trying to output a buffer to a file using visual c++.
my code for doing it is-
FILE *stream;
stream=fopen("C:\\Users\\sshekha\\Desktop\\z.txt","r");
//I also tried with "w" mode
//the differencein behavious on executing these two is that when it is in read mode it
//executes the else condition in the code below whereas in "w" mode it executes the "if"
// condition,
//moreover even if i change the path it don't execute the "else" condition-that means this path
//is effective to the code. and the another surprising thing is when i open the file manually
// and then run the code with "r" mode it still executes the "else" part (which it shouldn't
// because the file is already open.)
if( stream == 0 )
{
MessageBox(m_hwndPreview,L" the file is not opened ",L"BTN WND",MB_ICONINFORMATION);
}
else
{
MessageBox(m_hwndPreview,L" the file is opened ",L"BTN WND",MB_ICONINFORMATION);
int check=fputs (HtmlFileContents,stream);
fclose(stream);
return 0;
}
I tried to check the results using different mode in order to understand whats teh probem going on . when i debug it , i get the value of (in Read mode) :
stream = 0x000000005c5c76f0 { _ptr=0x0000000000000000 _cnt=0 _base=0x0000000000000000 ...}
I don't know it gib=ves bad pointer and even then it go to else part of the loop. Why ?
and in write mode
stream = 0x0000000000000000 {_ptr=??? _cnt=??? _base=??? ...}
So go to the if part of the loop.
Moreover my path is correct and i have enough permission to do the task I wish. But why does it give bad pointer ? Why have I these strange values of stream and what should I do to copy the content of my buffer HtmlFileContents in to z.txt ? Any ideas ?
You're opening the file in read-only mode: fopen("C:\\Users\\sshekha\\Desktop\\z.txt","r");. Here "r" says you only intend to read from file. To be able to write contents (i.e. fputs(...)), open the file in write mode like so: fopen("C:\Users\sshekha\Desktop\z.txt","w")(or"a"` if you want to append). For more information, read fopen documentation.
EDIT: I see that you've tried both read and write modes. You're code only shows read-mode and hence my assumption on the read-only problem. Let me do a bit more research and get back.
Please write the following code in your if statement:
perror("The following error occurred:");
if you don't have a console, use this to store the error string:
char* errorCause = strerror(errno); MessageBoxA(m_hwndPreview, errorCause, "BTN WND", MB_ICONINFORMATION);
and let us know what you see as the cause.
EDIT 2: Since you've mentioned that you're using Visual Studio 2010, are you running it as yourself? This stackoverflow answer shows that VS2010 has different options when debugging applications; https://stackoverflow.com/a/3704942/210634
NOTE: That feature is only available on 'Pro' versions.
Here's a working example: https://ideone.com/hVLgc4
If the file is "read only", opening with it with write permissions should fail.
to see if that is the case,under windows:
right click the file
press properties
at the bottom, see if "Read-only" attribute i marked with "v"
(uncheck it if you desire writing to the file)
refer to :
http://msdn.microsoft.com/en-us/library/aa365535(v=vs.85).aspx
on how to change file permissions from your code
I have added an image "padimage.png" to my resources folder and set add to target and make copy if needed checked. Then in my c++ code I have the following code to check if it can reach the file
std::ifstream my_file("padimage.png");
if (my_file.good())
{
std::cout << "could read file \n";
} else {
std::cout << "could not read file \n";
}
This fails meaning I can't reach the file. I have checked in the debug build folder and the image is there under the resources folder, I have also tried alternative paths to the file like "resources/padimage.png" || Resources/padimage.png || ../Resources/padimage.png etc. etc.
I am fairly new to c++ still so I don't quite understand how it is suppose to find files or what path it searches relative to. Also I am sure this is quite an easy problem but I somehow can't solve it.
All help is much appreciated.
Just for your own sanity, do the following before anything else.
char wd[1024];
std::cout << getcwd(wd, sizeof(wd)) << std::endl;
You may be surprised at where you are, and thus why you can't open your file. When running from the IDE you can specify the location of your working directory under the Product/Edit Schemes... area of Xcode (among other places).
Thanks to a suggestion from WhozCraig I have managed to get it working by using the root of the project and then creating a standalone file next to the application like so:
./padimage.png
however this is not ideal. This means I would have resources outside of the project.
But after some trial and error I managed to navigate into the programs package contents by using .app to the package name;
./ProjectName.app/Contents/Resources/padimage.png