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
Related
I made a program that runs automatically at startup, but my program does not perform the task of append text to the file when it runs automatically.
Here example code:
#include <Windows.h>
#include <fstream>
#include <iostream>
void AutoRun() {
LONG key;
std::string FP;
char re[MAX_PATH];
FP = std::string(re, GetModuleFileNameA(NULL, re, MAX_PATH));
HKEY hkey;
key = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\Currentversion\\Run", 0, KEY_WRITE, &hkey);
if (key == ERROR_SUCCESS)
{
std::cout << "paketi yüklüyoruzzz";
key = RegSetValueExA(hkey, "testzort", 0, REG_SZ, (BYTE*)FP.c_str(), strlen(FP.c_str()));
RegCloseKey(hkey);
}
else {
std::cout << "Maga mapket müklenemedi:(: " << key;
}
}
int main(){
// open output file in append mode
const char* output_filename = "testing.log";
std::cout << "Logging output to " << output_filename << std::endl;
output_file.open(output_filename, std::ios_base::app);
AutoRun();
output_file << "zozozort\n";
}
When I restart my computer after execute this code, not add my file like:
zozozort
zozozort
What is the problem ?
NOTE: For the first time to run the regedit api, I ran the program with administrator mode when starting
First off, consider using HKEY_CURRENT_USER instead of HKEY_LOCAL_MACHINE (unless you really want all users of your machine running your app). And consider using KEY_SET_VALUE instead of KEY_WRITE (which includes rights you don't need in this code). This will reduce the need for your code to run as an admin when setting up the auto-run.
In any case, when calling RegSetValueEx(), you are setting the data size to strlen(FP.c_str()), which is wrong, as RegSetValueEx() requires the null terminator to be included in the data size:
If the data is of type REG_SZ, REG_EXPAND_SZ, or REG_MULTI_SZ, cbData must include the size of the terminating null character or characters.
So, use strlen(FP.c_str())+1 instead, or better FP.size()+1.
That being said, your app is opening the text file using a relative path, so its location is relative to the app's current working directory, which you don't know what it is when your app is started (you can use GetCurrentDirectory() to determine that). Just because the text file is in the same folder as your app doesn't mean the working directory points to your app's folder. Always use absolute paths when creating/opening files.
If you were using CreateFile() instead of (o)fstream (BTW, where is your output_file variable declared?) to create/open the file, then you could use GetFinalPathNameByHandle() to determine its actual full path, so you can see if it is what you are expecting.
If your really want to create/open the text file in your app's folder, you already know how to get the app's full file path from GetModuleFileName(), so simply replace the filename portion after the last '\' character with your text file's name, and then use that full path to create/open the file. Just make sure your app is not running in a folder that denies write access to non-admins, such as Program Files.
You really should be writing the text file into a folder that is guaranteed to be accessible to the calling user (preferably within their own profile), instead of in the app's folder. For instance, get a user-accessible folder path via either:
SHGetFolderPath(), specifying something like CSIDL_(LOCAL_|COMMON_)APPDATA, CSIDL_DESKTOPDIRECTORY, CSIDL_MYDOCUMENTS, etc.
SHGetKnownFolderPath(), specifying something like FOLDERID_(Roaming|Local)AppData, FOLDERID_ProgramData, FOLDERID_Desktop, FOLDERID_Documents, etc.
Then, create your own subfolder underneath that folder, and create the file inside that subfolder.
I've written a small C++ program which checks if Windows clipboard content has changed and prints a type of that content. I compiled the program to .exe file using Windows Visual Studio 2019 and it was blocked by the Windows Defender (file was removed). Why is that happened and how to prevent it?
Of course, if I open the Windows Defender and mark my file as "not a virus" then all works fine, but how to prevent blocking on customers computers? Do I need to create some "manifest" file..?
Sorry if the question is dumb, I'm new in C++ world
#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <Windows.h>
#include <conio.h>
int main()
{
DWORD m_lastClipboardSequenceNumber = GetClipboardSequenceNumber();
while (1) {
Sleep(100);
const DWORD newClipboardSequenceNumber = GetClipboardSequenceNumber();
if (newClipboardSequenceNumber == m_lastClipboardSequenceNumber)
continue;
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
std::wcout << "CF_UNICODETEXT\n";
}
if (IsClipboardFormatAvailable(CF_HDROP)) {
std::wcout << "CF_HDROP\n";
}
if (IsClipboardFormatAvailable(CF_BITMAP)) {
std::wcout << "CF_BITMAP\n";
}
m_lastClipboardSequenceNumber = newClipboardSequenceNumber;
}
return 0;
}
Sounds like your issue isn't with C++ at all and more just with Windows, more precisely, Windows Defender. The issue here, to my knowledge, is that Windows Defender started by default not allowing .exe files from unknown sources to be run on the computer without Admin privileges. This is an issue you cannot fix remotely, otherwise that would massively undermine the existing usefulness of Windows Defender, as malicious actors could just use that to run their exploits.
Steps you could take to possibly fix this for your use case: if you have access to the computers you want to run this on, try adding your distribution method to trusted sources. Alternatively, try signing it with a key and adding that signature to trusted.
I personally think since your method for watching clipboard is too abusive, windows defender is blocking your code.
Try monitoring clipboard section and register listeners for clipboard changes to see if same thing happens or not. Your code will be much more complex, since you will need to create a window loop for receiving messages, but I think it will OK that way.
I am currently trying to fix a bug on a legacy application code in which it uses basically GetFileTime function to retrieve file information through a HANDLE obtained by using CreateFileW function.
Problem arises when it attempts to work with files that are already opened by other processes like *.ldf and *.mdf files which are opened by SQL Server. An error is thrown when trying to get the file HANDLE.
As an alternative, I noticed that boost library is being used as a dependency in the project so I found the following code sample working:
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
path filePath("path/to/the/file.ext");
std::cout << file_size(filePath) << "\n"; // Getting file size
std::cout << last_write_time(filePath) << "\n"; // Getting write/modified time
Using that piece of code we get the file size and the last write time. However, I still need the created and last accessed times. Any ideas how can I achieve it?
Boost FileSystem doesn't seem to support retrieving the creation/last accessed times for a file.
Under the circumstances, I'd probably use FindFirstFile (and FindClose) to get the information you want:
WIN32_FIND_DATA GetFileInfo(char const *path) {
WIN32_FIND_DATA data;
HANDLE h;
h = FindFirstFile(path, &data);
FindClose(h);
return data;
}
This doesn't require opening the file, so it can retrieve data about a file, even if that file is currently open in another process.
So, before starting, I have been researching (not only on Stack Overflow) and I can't find a solution to my problem.
I am trying to copy a file to a certain place (and if possible, change its name at the same time I copy it) using Windows' CopyFile function.
I've created a sample program to show the error.
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
cout << "Copy in progress" << endl;
bool X = CopyFile(L"test.txt", L"C:\\", 1); //NOT C: nor C:\\
if (!X){ cout << "FALLO AL COPIAR\n"; cout << "Error: "<<GetLastError();}
else{ cout << "COPIADO CORRECTO"; }
cin.get(); cin.get();
return 0;
}
GetLastError() returns 3 - which means ERROR_PATH_NOT_FOUND - but, believe me, I've checked every file (test.txt is in the same place as the built .exe, I'm running as admin...) and it still gives 3.
I can't manage to make it work. Notice the L"test" this is done because I use Visual Studio with certain character set settings, I've tried to change that config and use "test.txt" -> Still error 3.
You need to provide a filename:
bool X = CopyFile(L"test.txt", L"C:\\test.txt", 1);
You may check the function signature from the MSDN:
BOOL WINAPI CopyFile(
_In_ LPCTSTR lpExistingFileName,
_In_ LPCTSTR lpNewFileName,
_In_ BOOL bFailIfExists
);
I suppose, it requires not target directory (as e.g. cp command would), but the entire file name. Hint: make sure that all directories before the final file name are created when you call CopyFile.
Yet another hint: on POSIX systems, you have no similar routine (well, you have something similar on OS X, but it's OS-specific). However, here's what you can do (and this is how CopyFile actually works behind the scene):
Open two file handles via open for POSIX or CreateFile for Windows. One handle is opened for reading (source file) and the other one is opened for writing (destination file).
Read from the handle that you opened for reading into the temporary buffer (BUFSIZ buffer size is usually enough).
Write the data from the buffer into the handle opened for writing.
Repeat until there are bytes available into the readable handle.
This is how it generally works, though OS-specific routines may be tuned with some black magic (e.g. they can perform memory mapping, send file from one descriptor into the other without exiting from kernel mode, etc.).
try:
CopyFile(L"test.txt", L"C:\\test.txt", 1);
Simply put, I double click on image1 in its file and it opens. I run the code bellow to open image1 and nothing comes up. So I go into the file with image1 again, double click on it, and windows photo viewer said, "Windows Photo Viewer can't display this picture because the file is empty." I did this with two other test images and the same thing is happening. Nothing important has been lost but this method seems to be erasing whichever file it tries to open and I'm very curious as to why and how I can fix it.
#include <iostream>
#include <fstream>
#include <chrono>
#include <thread>
void main()
{
std::ofstream imagetest;
imagetest.open("C:\\Users\\Filepath\\image1.jpg");
std::chrono::milliseconds dura(2000);
std::this_thread::sleep_for(dura);//Kept the sleep in because I didn't know if having the console up would affect the file/image from opening.
}
C++ is at lower level than scripts. open does not mean START.
You will have to execute a batch script with START C:\Users\Filepath\image1.jpg.
Or to learn many more libraries to do that in C++...
ofstream stands for “output file stream”. In addition to creating files that doesn’t exist, it also erases the contents of files that do exist. So you are opening an existing file for writing, and blowing away its contents in the process. You probably want ifstream, “input file stream”, for reading.
If you want to “open” the file in the sense of launching the default Windows application to read the file, you can use the Windows start command via system:
system("start \"C:\\Users\\Filepath\\image1.jpg\"");
Or the Windows ShellExecute API:
#include <windows.h>
ShellExecute(
NULL,
"open",
"C:\\Users\\Filepath\\image1.jpg",
NULL,
NULL,
SW_SHOWNORMAL
);
First,
std::ofstream imagetest;
is using the kernel to open the file for reading the file data..
this is probably what is corrupting the file from "opening" when you double click on it in windows
if you want to have windows open the image for viewing using the default application then you need a different method call because ofstream.open is not what you want.
try:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx
ShellExecute(NULL,"open","C:\\Users\\Filepath\\image1.jpg",NULL,NULL,SW_SHOW);
If you open a file stream for WRITE, then it will wipe all the content of that file, just like when you do that on a txt file. So you would always want to open the stream for read mode if you don't want that to happen