I am doing a software project with Visual Studio Professional 2010.
In the form that I am making, I would like to put a link to open Microsoft Paint. How can I execute another application (MSPaint) from mine?
Call ShellExecute() passing open as the verb and mspaint.exe as the filename.
ShellExecute(
MainFormWindowHandle,
"open",
"mspaint.exe",
NULL,
NULL,
SW_SHOW
);
My contribution a complete example:
Go to Visual Studio, create a new Win32 C++ Project (not console), and paste the following code in the source file will appear:
// Win32Project1.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "Win32Project1.h"
#include "shellapi.h"
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
ShellExecuteA ( NULL, "open",
"your.exe",
"your params",
"working dir", SW_SHOW);
return TRUE;
}
Myself I contribute the following code which can be used in Windows
#include <iostream>
#include<Windows.h>
using namespace std;
int main()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD dwProcessId = 0;
DWORD dwThreadId = 0;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
bool bCreateProcess = NULL;
bCreateProcess = CreateProcess((Location of Paint path),0,0,0,0,0,0,0,&si, pi);
//Instead of 0 NULL can also be used
if (bCreateProcess == FALSE)
cout << " Creation Process Failed ";
else
cout << " Process Executedd ";
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
Related
I ran into some troubles when attempting a Detours hook on CreateFile in this small program:
#include <windows.h>
#include <iostream>
int main(HINSTANCE hinst, HINSTANCE hPrevInstance, LPSTR cmdLine, int showCmd)
{
HANDLE file;
DWORD bytesRead, bytesWritten, pos;
TCHAR msg[1000];
std::cout << "Start creating file \"SampleFile.txt\"" << std::endl;
file = CreateFile(L"C:\\TestHook\\SampleFile.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
std::cout << "\"SampleFile.txt\" added into C folder" << std::endl;
CloseHandle(file);
return 0;
}
There is a DLL applied:
#include<windows.h>
#include<windows.h>
#include "C:\Detours\Detours-4.0.1\include\detours.h"
static HANDLE(WINAPI* TrueCreateFile)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile) = CreateFileW;
__declspec(dllexport) HANDLE WINAPI MyCreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD
dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
HANDLE hookFile = CreateFile(L"C:\\TestHook\\hookYouGo.txt", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
std::cout << "CreateFile() is hooked...Meet other file name than you want" << std::endl;
CloseHandle(hookFile);
return hookFile;
}
BOOL WINAPI DLLMain(HINSTANCE hinst, DWORD reason_for_call, LPVOID lpReserved)
{
std::cout << "test" << std::endl;
if (reason_for_call = DLL_PROCESS_ATTACH)
{
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)TrueCreateFile, MyCreateFile);
DetourTransactionCommit();
}
return TRUE;
}
Once executing in Visual Studio '19 (OS Windows 10), it adds a new file into the target folder, but another than I expect. Instead of hookYouGo.txt, SampleHook.txt appears there as if hook attachment failed. Looking into API monitor after process finish, I don't find any evidence that DLL was applied as orderly as well. In command line, it's just the same, since I launch withdll.exe that runs into outputs like statements on SampleFile, but DLL stuff seems beyond that process. Both withdll.exe and main func program and DLL are inside the same folder, sure.
You are doing it the wrong way, you must get the function address in order to hook it.
Like this:
static HANDLE(WINAPI* TrueCreateFile)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile);
TrueCreateFile HookCreateFile;
HookCreateFile = (TrueCreateFile)GetProcAddress(GetModuleHandle("Kernel32.dll"), "CreateFile");
Then do the actual hooking:
DetourAttach(&(PVOID&)HookCreateFile, MyCreateFile);
I wrote a simple application on Qt4 that modifier network adapter parameters, for that I have a slot called setInterfaceParams, implemented as so:
DWORD WinNetInterface::setInterfaceParams(QString index, QString ip, QString netmask, QString gateway)
{
DWORD res = NULL;
HINSTANCE lib = (HINSTANCE) LoadLibrary((WCHAR *)"iphlpapi.dll");
_SetAdapterIpAddress SetAdapterIpAddress = (_SetAdapterIpAddress) GetProcAddress(lib, "SetAdapterIpAddress");
PWSTR pszGUID = NULL;
//char *szGUID = (char *)index.toStdString().c_str();
QByteArray a = index.toLocal8Bit();
char *szGUID = a.data();
WideCharToMultiByte(CP_ACP, 0, pszGUID, -1, szGUID, sizeof(szGUID), NULL, NULL);
// Method 01
res = SetAdapterIpAddress(szGUID,
0,
inet_addr(ip.toStdString().c_str()),
inet_addr(netmask.toStdString().c_str()),
inet_addr(gateway.toStdString().c_str()));
// End of method 01
// Method 02
/*res = SetAdapterIpAddress("{422C5689-A17B-402D-A6A2-22CE13E857B5}",
0,
inet_addr("192.168.1.10"),
inet_addr("255.255.255.0"),
inet_addr("192.168.1.1"));*/
// End of method 02
return res;
}
When I click on button that connected to slot setInterfaceParams, I get segmentation fault. If I comment method01, nothing happen, the some thing happen when I use method02.
I tried this function on a simple c++ application and it is work fine, test on Windows XP SP3.
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <iostream>
typedef DWORD (WINAPI *_SetAdapterIpAddress )(char *szAdapterGUID,
DWORD dwDHCP,
DWORD dwIP,
DWORD dwMask,
DWORD dwGateway);
int main()
{
HINSTANCE lib = (HINSTANCE) LoadLibrary("iphlpapi.dll");
_SetAdapterIpAddress SetAdapterIpAddress = (_SetAdapterIpAddress) GetProcAddress(lib, "SetAdapterIpAddress");
PWSTR pszGUID = NULL;
char szGUID[] = "{422C5689-A17B-402D-A6A2-22CE13E857B5}";
DWORD dwSize = 0;
WideCharToMultiByte(CP_ACP, 0, pszGUID, -1, szGUID, sizeof(szGUID), NULL, NULL);
DWORD res = SetAdapterIpAddress(szGUID,
0,
inet_addr("192.168.1.10"),
inet_addr("255.255.255.0"),
inet_addr("192.168.1.1"));
std::cout << res;
return 0;
}
LoadLibrary((WCHAR *)"iphlpapi.dll");
That can't work, the literal string is in 8-bits, casting it without real conversion doesn't make it wide, so the dll loading probably failed.
You should use the TEXT or _T macro around most of the literal strings passed to WinAPI functions to make them regular or wide depending on the compilation options:
LoadLibrary(_T("iphlpapi.dll"));
which will translate to either LoadLibrary("iphlpapi.dll"); or LoadLibrary(L"iphlpapi.dll");.
Also you should always check the value returned by the LoadLibrary and GetProcAddress functions, which return NULL if the call is unsuccessful.
I've been trying to write a program in C++ that will monitor running processes in the background and terminate a certain one if it's detected to be running. I have written a program that will do so, however the only way I can think of to do this is to use an infinite WHILE loop that keeps checking for the program. This, as you can imagine, constantly uses CPU power and resources to be constantly looping. In task manager, you can see that most processes that are running are always using 0% of the CPU. My question is: How can I write or modify this program to run in the background, utilizing 0% of the CPU until it detects the process it's supposed to terminate?
My entire program is below. In this example, I have used "Notepad.exe" in WinMain as the process the program should be terminating.
#include <Windows.h>
#include <iostream>
#include <tlhelp32.h>
#include <string>
#define TA_FAILED 0
#define TA_SUCCESS_CLEAN 1
#define TA_SUCCESS_KILL 2
DWORD WINAPI TerminateApp(DWORD dwPID, DWORD dwTimeout);
DWORD WINAPI Terminate16App(DWORD dwPID, DWORD dwThread, WORD w16Task, DWORD dwTimeout);
typedef struct {
DWORD dwID;
DWORD dwThread;
} TERMINFO;
BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) ;
DWORD WINAPI TerminateApp( DWORD dwPID, DWORD dwTimeout ) {
HANDLE hProc ;
DWORD dwRet ;
// If we can't open the process with PROCESS_TERMINATE rights,
// then we give up immediately.
hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE,
dwPID);
if(hProc == NULL) {
return TA_FAILED ;
}
// TerminateAppEnum() posts WM_CLOSE to all windows whose PID
// matches your process's.
EnumWindows((WNDENUMPROC)TerminateAppEnum, (LPARAM) dwPID) ;
// Wait on the handle. If it signals, great. If it times out,
// then you kill it.
if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0)
dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED);
else
dwRet = TA_SUCCESS_CLEAN ;
CloseHandle(hProc) ;
return dwRet ;
}
BOOL CALLBACK TerminateAppEnum( HWND hwnd, LPARAM lParam ) {
DWORD dwID ;
GetWindowThreadProcessId(hwnd, &dwID) ;
if(dwID == (DWORD)lParam) {
PostMessage(hwnd, WM_CLOSE, 0, 0) ;
}
return TRUE ;
}
DWORD FindProcessId(const std::string& processName);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
std::string process1 = "Notepad.exe";
while (1) {
TerminateApp(FindProcessId(process1),0);
}
return 0;
}
DWORD FindProcessId(const std::string& processName) {
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo);
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (processesSnapshot == INVALID_HANDLE_VALUE) {
return 0;
}
Process32First(processesSnapshot, &processInfo);
if (!processName.compare(processInfo.szExeFile)) {
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
while (Process32Next(processesSnapshot, &processInfo)) {
if (!processName.compare(processInfo.szExeFile)) {
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}
}
CloseHandle(processesSnapshot);
return 0;
}
You can use WMI and event notification to find when processes are created and destroyed. __InstanceCreationEvent is what you need to look for.
Creation of a resource: __InstanceCreationEvent
Suppose you are interested in receiving a notification if Notepad is run on a certain computer. When Notepad runs, a corresponding process is created. Processes can be managed by using WMI and are represented by the Win32_Process class. When Notepad starts running, a corresponding instance of the Win32_Process class becomes available through WMI. If you have registered your interest in this event (by issuing the appropriate event notification query), the availability of this instance results in the creation of an instance of the __InstanceCreationEvent class.
I created a win32 console application (without enable precompiled header option).
And now my source code as this, there is two compiler errors.
// AFormattingMsgBox.cpp : Defines the entry point for the console application.
//
#include <windows.h>
#include "stdafx.h"
//int _tmain(int argc, _TCHAR* argv[])
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
int cxScreen, cyScreen;
cxScreen = GetSystemMetrics(SM_CXSCREEN);
cyScreen = GetSystemMetrics(SM_CYSCREEN);
MessageBoxPrintf(TEXT("ScrnSize"), TEXT("The screen is %i pixels wide by %i pixels high."), cxScreen, cyScreen);
return 0;
}
int CDECL MessageBoxPrintf(TCHAR * szCaption, TCHAR * szFormat, int x, int y)
{
TCHAR szBuffer [1024];
va_list pArgList;
va_start(pArgList, szFormat);
_vsntprintf(szBuffer, sizeof(szBuffer) / sizeof(TCHAR),
szFormat, pArgList);
va_end(pArgList);
return MessageBox(NULL, szBuffer, szCaption, 0);
}
Compiler Errors.
error C3861: 'MessageBoxPrintf': identifier not found
error C2365: 'MessageBoxPrintf' : redefinition; previous definition was 'formerly
unknown identifier
How can I fix the errors. Thanks for your reading and replies.
Either put the function MessageBoxPrintf before the WinMain function or add a prototype before winMain. You add a prototype by entering the following line:
int CDECL MessageBoxPrintf(TCHAR * szCaption, TCHAR * szFormat, int x, int y);
#include <windows.h>
#include <stdio.h>
#include <Userenv.h>
#include <Wtsapi32.h>
int main() {
DWORD err;
err=GetLastError();
printf( "err001:%d\n",err);
HANDLE hTokenThis = NULL;
HANDLE hTokenDup = NULL;
HANDLE hThisProcess = GetCurrentProcess();
OpenProcessToken(hThisProcess, TOKEN_ALL_ACCESS, &hTokenThis);
err=GetLastError();
printf( "err002:%d\n",err);
DuplicateTokenEx(hTokenThis, MAXIMUM_ALLOWED,NULL, SecurityIdentification, TokenPrimary, &hTokenDup);
err=GetLastError();
printf( "err003:%d\n",err);
DWORD dwSessionId = WTSGetActiveConsoleSessionId();
WTSQueryUserToken(dwSessionId, hTokenDup);
//DWORD dwSessionId = 1;
SetTokenInformation(hTokenDup, TokenSessionId, &dwSessionId, sizeof(DWORD));
err=GetLastError();
printf( "err004:%d\n",err);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "WinSta0\\Default";
LPVOID pEnv = NULL;
DWORD dwCreationFlag = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
CreateEnvironmentBlock(&pEnv, hTokenDup, FALSE);
err=GetLastError();
printf( "err005:%d\n",err);
CreateProcessAsUser(
hTokenDup,
NULL,
(char *)"notepad",
NULL,
NULL,
FALSE,
dwCreationFlag,
pEnv,
NULL,
&si,
&pi);
printf("here we go\n");
err=GetLastError();
printf( "err006:%d\n",err);
return 0;
}
Compile:
gcc -o session.exe session.c c://Windows/System32/kernel32.dll c://Window
s/System32/wtsapi32.dll -lUserenv
Running Result:
session.exe
err001:126
err002:126
err003:126
err004:1314
err005:203
here we go
err006:87
gcc version 4.5.2 (GCC) from mingw.
btw, just ignore the error 126.
My question is :
Why got error 1314?
I want to start a program in the interactive desktop from service by using CreateProcessAsUser without knowing the logon user and password.
Error 1314 is "A required privilege is not held by the client".
From the WTSQueryUserToken() docs (http://msdn.microsoft.com/en-us/library/aa383840.aspx):
To call this function successfully, the calling application must be running within the context of the LocalSystem account and have the SE_TCB_NAME privilege
Also your call to WTSQueryUserToken() should look like:
WTSQueryUserToken(dwSessionId, &hTokenDup);
And you'll need appropriate privileges for SetTokenInformation() enabled as well.
Bottom line is that you're trying to do something that Windows reserves for highly privileged processes, so you'll need to make sure your process is configured to run appropriately (maybe as a service that talks to a regular non-privileged process for user interaction).