results from debug diff from release - c++

I have this code here:
#include "windows.h"
#include "Tlhelp32.h"
#include "shellapi.h"
#include <wchar.h>
#include <fstream>
bool enumProcesses();
int main()
{
enumProcesses();
ShellExecute( NULL, L"open", L"log.txt", NULL, NULL, SW_SHOW );
return 0;
}
bool enumProcesses()
{
std::wofstream log("log.txt");
PROCESSENTRY32 lppe;
MODULEENTRY32 lpme;
HANDLE hSnapshot;
HANDLE mSnapshot;
lppe.dwSize = sizeof( PROCESSENTRY32 );
lpme.dwSize = sizeof( MODULEENTRY32 );
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hSnapshot == INVALID_HANDLE_VALUE )
{
log << L"Error creating process snapshot.";
return false;
}
if( !Process32First( hSnapshot, &lppe ) )
{
log << L"Error enumerating first process.";
return false;
}
else
{
mSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, lppe.th32ProcessID );
if( mSnapshot != INVALID_HANDLE_VALUE )
{
Module32First( mSnapshot, &lpme );
}
if( wcscmp( lppe.szExeFile, L"[System Process]" ) != 0 )
{
log << lpme.szExePath << "\n";
}
}
while( Process32Next( hSnapshot, &lppe ) )
{
if( wcscmp( lppe.szExeFile, L"System" ) != 0 )
{
if( (mSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, lppe.th32ProcessID )) != INVALID_HANDLE_VALUE )
{
if( Module32First( mSnapshot, &lpme ) ) {
log << lpme.szExePath << "\n";
}
}
}
}
CloseHandle( hSnapshot );
CloseHandle( mSnapshot );
log.close();
return true;
}
My problem is that whenever I debug this code in VC++ using F5 or CTRL + F5, it shows me all the processes but when I create a release version and run it, some things don't even show anymore and I'm not sure why..
Here's what I'm talking about:
release version:
C:\WINDOWS\Explorer.EXE
C:\Program Files\Java\jre6\bin\jusched.exe
C:\WINDOWS\system32\ctfmon.exe
C:\Program Files\Messenger\msmsgs.exe
C:\WINDOWS\system32\wscntfy.exe
C:\WINDOWS\system32\wuauclt.exe
c:\Program Files\Microsoft Visual Studio 9.0\Common7\ide\mspdbsrv.exe
C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe
C:\Program Files\Mozilla Firefox\firefox.exe
C:\Documents and Settings\windows\Desktop\c++ projects\gggg\Debug\gggg.exe
log created on debug:
\SystemRoot\System32\smss.exe
\??\C:\WINDOWS\system32\csrss.exe
\??\C:\WINDOWS\system32\winlogon.exe
C:\WINDOWS\system32\services.exe
C:\WINDOWS\system32\lsass.exe
C:\WINDOWS\system32\svchost.exe
C:\WINDOWS\system32\svchost.exe
C:\WINDOWS\System32\svchost.exe
C:\WINDOWS\system32\svchost.exe
C:\WINDOWS\system32\svchost.exe
C:\WINDOWS\system32\spoolsv.exe
C:\WINDOWS\Explorer.EXE
C:\Program Files\Java\jre6\bin\jusched.exe
C:\WINDOWS\system32\ctfmon.exe
C:\Program Files\Messenger\msmsgs.exe
C:\Program Files\Java\jre6\bin\jqs.exe
c:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\sqlservr.exe
c:\Program Files\Microsoft SQL Server\90\Shared\sqlwriter.exe
C:\WINDOWS\System32\alg.exe
C:\WINDOWS\system32\wscntfy.exe
C:\WINDOWS\system32\wuauclt.exe
c:\Program Files\Microsoft Visual Studio 9.0\Common7\ide\mspdbsrv.exe
C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe
C:\Program Files\Mozilla Firefox\firefox.exe
C:\WINDOWS\system32\NOTEPAD.EXE
C:\WINDOWS\system32\cmd.exe
c:\Documents and Settings\windows\Desktop\c++ projects\gggg\Release\gggg.exe
Does it have something to do with permissions?
EDIT:
Looking at 1800 INFORMATION's post, I tried to "force" it to run under SYSTEM account by using psexec -i -d -s and it worked... Is there any way I could run this without the need of doing such a thing?

I bet that when you debug it, you are running it from within Visual Studio with administrator privileges, while when you run the release build, it does not so it will not be able to see all of the processes in the system. This is the same reason that task manager cannot list all of the running processes unless you elevate.

Related

Fstream does not recognise relative path [duplicate]

I wrote a simple check_file_ref function using WinAPI to check whether two paths reference the same file. The code is fine. It's compiled with Visual Studio 2017 in C (flag /TC).
The weird thing is CreateFileA (winapi) always fails when the executable is run under Visual Studio (ie execute without debugging), returning an invalid file handle. Otherwise, it works as expected when the executable is run outside of Visual Studio.
The working dir is the same in any case.
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
/**
* Check whether two paths reference the same file.
* #param p1 File path 1.
* #param p2 File path 2.
* #return 0 same file, 1 different files, < 0 on failure.
*/
int
check_file_ref(char const * p1, char const * p2)
{
if ( !p1 || !p2 )
return -1;
if ( p1 == p2 )
return 0;
if ( strcmp(p1, p2) == 0 )
return 0;
int ret;
DWORD share, flags;
HANDLE f1, f2;
BY_HANDLE_FILE_INFORMATION s1, s2;
ret = -1;
share = FILE_SHARE_READ | FILE_SHARE_WRITE;
flags = FILE_ATTRIBUTE_NORMAL;
f1 = CreateFileA(p1, GENERIC_READ, share, NULL, OPEN_EXISTING, flags, NULL);
f2 = CreateFileA(p2, GENERIC_READ, share, NULL, OPEN_EXISTING, flags, NULL);
if ( f1 == INVALID_HANDLE_VALUE ) {
fprintf(stderr, "Could not open %s file, error %d\n", p1, GetLastError());
goto cleanup;
}
if ( f2 == INVALID_HANDLE_VALUE ) {
fprintf(stderr, "Could not open %s file, error %d\n", p2, GetLastError());
goto cleanup;
}
if ( GetFileInformationByHandle(f1, &s1) == 0 ) {
fprintf(stderr, "Could not get %s file information, error %d\n", p1, GetLastError());
goto cleanup;
}
if ( GetFileInformationByHandle(f2, &s2) == 0 ) {
fprintf(stderr, "Could not get %s file information, error %d\n", p2, GetLastError());
goto cleanup;
}
/*
The identifier (low and high parts) and the volume serial number uniquely
identify a file on a single computer. To determine whether two open handles
represent the same file, combine the identifier and the volume serial number
for each file and compare them.
See
https://learn.microsoft.com/fr-fr/windows/desktop/api/fileapi/nf-fileapi-getfileinformationbyhandle
https://learn.microsoft.com/fr-fr/windows/desktop/api/fileapi/ns-fileapi-_by_handle_file_information
*/
ret = !(s1.dwVolumeSerialNumber == s2.dwVolumeSerialNumber
&& s1.nFileIndexLow == s2.nFileIndexLow
&& s1.nFileIndexHigh == s2.nFileIndexHigh);
cleanup:
CloseHandle(f2);
CloseHandle(f1);
return ret;
}
int main()
{
int ret;
char workingDir[256];
/* Both paths reference the same file.
One is relative, the other absolute. */
char * p1 = "hello.txt";
char * p2 = "C:/Users/bro/source/repos/tests/x64/Debug/hello.txt";
ret = GetModuleFileNameA(NULL, workingDir, sizeof(workingDir));
printf("working dir: %s\n", (ret == 0 ? "err" : workingDir));
/* Should return 0. */
ret = check_file_ref(p1, p2);
printf("p1: %s\n", p1);
printf("p2: %s\n", p2);
printf("check_file_ret ret %d ", ret);
if ( ret == 0 ) printf("(same file)\n");
else if ( ret == 1 ) printf("(different files)\n");
else printf("(error)\n");
return 0;
}
Executable run under visual:
CreateFileA fails
Executable run directly from cmd line:
CreateFileA works
Why is CreateFileA failing only when the executable is run under Visual Studio?
When you run an application from VisualStudio the default working directory is a project location, which is defined by VS macro $(ProjectDir). You can change it by openning the project properties: Right click on the project in Solution Explorer and select Properties from the context menu. There select Debugging and change Working Directory property. For example, in your case the solution could be $(OutDir) or absolute path to the required location.

How to check if any file exist in specific folder?

I am using CreateProcess to copy files. Also I can catch different errors, if PC is offline, if directory does not exist.
Here is the problem I have: It returns 0 as error code, if all copying is successful and also returns 0 if there were zero files in source folder, so no copying is done. I must detect whether there are no files in source folder. How can I do it in MFC VC++ 2013?
I have spent hours trying different solutions, but my knowledge is not high enough to implement all I find on internet. So I have to ask for code, then I will understand. Thank you in advance.
This is code I use:
temp_dest = _T("/min /c xcopy \"D:\\Test\\*.*\" \"") + m_destination + _T("\" /Y /E /Q");
LPTSTR temp_dest2 = (LPTSTR)(LPCTSTR)temp_dest;
STARTUPINFO sinfo;
PROCESS_INFORMATION pinfo;
memset(&sinfo, 0, sizeof(STARTUPINFO));
memset(&pinfo, 0, sizeof(PROCESS_INFORMATION));
sinfo.dwFlags = STARTF_USESHOWWINDOW;
sinfo.wShowWindow = SW_HIDE;
BOOL bSucess = CreateProcess(L"C:\\Windows\\System32\\cmd.exe", temp_dest2, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &sinfo, &pinfo);
DWORD dwCode;
TerminateProcess(pinfo.hProcess, 2);
GetExitCodeProcess(pinfo.hProcess, &dwCode);
TCHAR msg2[100];
StringCbPrintf(msg2, 100, TEXT("%X"), dwCode);
MessageBox(msg2, (LPCWSTR)L"DWCode 2", MB_OK | MB_ICONERROR);
if (dwCode == 4)
{
MessageBox((LPCWSTR)L"DW 4", (LPCWSTR)L"Path not found", MB_OK | MB_ICONERROR);
}
if (dwCode == 2)
{
MessageBox((LPCWSTR)L"DW 4", (LPCWSTR)L"PC Offline", MB_OK | MB_ICONERROR);
}
If you can use directory_iterator from <filesystem> header file introduced in C++17:
bool IsEmptyDirectory( const wchar_t* dir )
{
return std::filesystem::directory_iterator( std::filesystem::path( dir ) )
== std::filesystem::directory_iterator();
}
May be needed std::experimental::filesystem instead of std::filesystem.
I have tried to port it to VC 2013, but only char version seems to compile
bool IsEmptyDirectory( const char* dir )
{
return std::tr2::sys::directory_iterator( std::tr2::sys::path( dir ) )
== std::tr2::sys::directory_iterator();
}
If you want (or have) to use WinAPI:
bool IsEmptyDirectory( const wchar_t* dir )
{
wstring mask( dir);
mask += L"\\*";
WIN32_FIND_DATA data;
HANDLE find_handle = FindFirstFile( mask.c_str(), &data );
if ( find_handle == INVALID_HANDLE_VALUE )
{
// Probably there is no directory with given path.
// Pretend that it is empty.
return true;
}
bool empty = true;
do
{
// Any entry but . and .. means non empty folder.
if ( wcscmp( data.cFileName, L"." ) != 0 && wcscmp( data.cFileName, L".." ) != 0 )
empty = false;
} while ( empty && FindNextFile( find_handle, &data ) );
FindClose( find_handle );
return empty;
}
You can use the WIN32 function GetFileAttributes(..) to check if a file exists or not:
if (GetFileAttributes("C:\\test.txt") != INVALID_FILE_ATTRIBUTES)
{
/* C:\test.txt is existing */
}
Another way just might be trying to open the file (and if successful to close it again).

Boost Library to find parent's process ID

I am really messed up with the code base I have and I am working on portability of C++ code.
As of now the code seems to be windows specific and it tries to take the parent's process ID that is executing itself. Eg: I write a code in C++ that uses the Parent's process ID of the cmd that is executing the corresponding EXE created by its (code's)compilation.
DWORD getParentPID()
{
HANDLE hSnapshot;
PROCESSENTRY32 pe32;
DWORD parentPID = 0, PID = GetCurrentProcessId();
hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
__try{
if( hSnapshot == INVALID_HANDLE_VALUE ) __leave;
ZeroMemory( &pe32, sizeof( pe32 ) );
pe32.dwSize = sizeof( pe32 );
if( !Process32First( hSnapshot, &pe32 ) ) __leave;
do{
if( pe32.th32ProcessID == PID ){
parentPID = pe32.th32ParentProcessID;
break;
}
}while( Process32Next( hSnapshot, &pe32 ) );
}
__finally{
if( hSnapshot != INVALID_HANDLE_VALUE ) CloseHandle( hSnapshot );
}
return parentPID;
}
Obviously, this code is not intended to work on Linux and I don't want any precompilation, Looking forward to some platform independent code using Boost C++.
PS: Precompilation up to som extent is accepted. Mainly Targeted platforms are Windows and Linux.I might be missing on some small points due to the workload.
Any Lead is appreciated, thanks in advance.

Serial Comms between Microsoft Visual C++ 2010 and Arduino UNO via USB

I need to establish a serial comm between Microsoft Windows Visual C++ 2010 and an Arduino microcontroller via USB. A motion tracking algorithm produces an X and Y coordinate which needs to be sent to the Arduino which in turn controls two pan and tilt servos.
I am a final year mechanical engineering student and have very little experience with Microsoft Visual Studios and C++, so please bear with me and please forgive me if my terms are incorrect...
I have done extensive research on multiple forums, but cannot find an answer specific to my problem:
All the solutions that I have come across only support comms when a normal/"empty" project is created in Visual Studios. An example can be found here: Serial communication (for Arduino) using Visual Studio 2010 and C
When I try and debug the same body of code (which successfully runs in an "empty" project) in a "Win32 Console Application" project, I am presented with the following errors:
error C2065: 'LcommPort' : undeclared identifier
error C2228: left of '.c_str' must have class/struct/union
Unfortunately I cannot simply change my project from a "Win32 Console Application" to a normal "Empty" project due to the fact that the motion tracking algorithm necessitates the use of the console application type of project.
The main body of code that I am using is as follows (this is a simplified test source file to confirm whether comms are established between MS Visual and the Arduino where the frequency at which an LED turns on and off is altered through the serial connection):
#include <Windows.h>
#include "ArduinoSerial.h"
#include "StdAfx.h"
int main() {
try {
ArduinoSerial arduino( "COM3" );
Sleep( 2000 ); // Initial wait to allow Arduino to boot after reset
char buffer[] = { 25, 100 };
arduino.Write( buffer, 2 ); // Send on/off delays to Arduino (if return value is 0, something went wrong)
}
catch ( const ArduinoSerialException &e ) {
MessageBoxA( NULL, e.what(), "ERROR", MB_ICONERROR | MB_OK );
}
return 0;
}
The corresponding source code which is the home of the error is found in line9 of the code:
#include <algorithm>
#include <sstream>
#include <Windows.h>
#include "stdafx.h"
#include "ArduinoSerial.h"
ArduinoSerial::ArduinoSerial( const std::string commPort ) {
comm = CreateFile( TEXT( commPort.c_str() ),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL );
if ( comm == INVALID_HANDLE_VALUE ) {
std::ostringstream error;
error << "Unable to acquire handle for " << commPort << ": ";
DWORD lastError = GetLastError();
if ( lastError == ERROR_FILE_NOT_FOUND ) {
error << "Invalid port name";
}
else {
error << "Error: " << lastError;
}
throw ArduinoSerialException( error.str() );
}
DCB dcb;
SecureZeroMemory( &dcb, sizeof DCB );
dcb.DCBlength = sizeof DCB;
dcb.BaudRate = CBR_9600;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.Parity = NOPARITY;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
if ( !SetCommState( comm, &dcb ) ) {
CloseHandle( comm );
std::ostringstream error;
error << "Unable to set comm state: Error " << GetLastError();
throw ArduinoSerialException( error.str() );
}
PurgeComm( comm, PURGE_RXCLEAR | PURGE_TXCLEAR );
}
std::size_t ArduinoSerial::Read( char buffer[], const std::size_t size ) {
DWORD numBytesRead = 0;
BOOL success = ReadFile( comm, buffer, size, &numBytesRead, NULL );
if ( success ) {
return numBytesRead;
}
else {
return 0;
}
}
std::size_t ArduinoSerial::Write( char buffer[], const std::size_t size ) {
DWORD numBytesWritten = 0;
BOOL success = WriteFile( comm, buffer, size, &numBytesWritten, NULL );
if ( success ) {
return numBytesWritten;
}
else {
return 0;
}
}
ArduinoSerial::~ArduinoSerial() {
CloseHandle( comm );
}
ArduinoSerialException::ArduinoSerialException( const std::string message ) :
std::runtime_error( message ) {
}
Any help or advice will be really greatly appreciated.
I am presented with the following errors:
error C2065: 'LcommPort' : undeclared identifier error C2228: left of '.c_str' must have class/struct/union
This little piece of code
TEXT( commPort.c_str())
becomes actually
LcommPort.c_str()
That's why you get this compiler error.
You should notice that TEXT() is a preprocessor macro meant for character literals, to prefix them with L depending in which mode (Unicode/ASCII) your project is compiled. It doesn't work with any variables obviously.
Use either commPort.c_str() directly, or const std::wstring commPort.

Setting PATH variable is not working

I apologize for the vague title, was not sure how to categorize my problem.
I have a script which I call from a Visual Studio 2013 project (C++). In that script, I try to set my path variable. When the PATH variable gets set, it seems like the it is including visual studio stuff in the path and copying the path more than once. Not sure why.
Note: Running the bat directly and running from the command prompt does not present this error.
.cpp:
int main(void)
{
system("CALL C:\\HFSS\\setup_vars.bat");
return 0;
}
.bat:
:: Set PATH Variable
set path_str=%PATH%
set addPath=%ValueValue%
echo %addPath%
echo %ValueValue%
PAUSE
echo %PATH%| find /i "%addPath%">NUL
if NOT ERRORLEVEL 1 (
SETX PATH "%PATH%
) else (
SETX /M PATH "%PATH%;%addPath%;"
)
Path which gets added:
C:\Program Files\AnsysEM\AnsysEM15.0\Win64;
C:\Program Files\AnsysEM\AnsysEM15.0\Win64;
C:\Program Files\AnsysEM\AnsysEM15.0\Win64;
C:\Program Files\AnsysEM\AnsysEM15.0\Win64;
C:\Program Files\AnsysEM\AnsysEM15.0\Win64;
C:\Program Files (x86)\Microsoft Visual Studio 12.0\;
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\amd64
UPDATE:
I did some research on CreateProcess and how to create a new environment block.
The following code triggers a break point:
#include <iostream>
#include <Windows.h>
#define WINDOWS_LEAN_AND_MEAN
#include <strsafe.h>
#define BUFSIZE 4096
int main(void)
{
LPTSTR lpszCurrentVariable;
TCHAR szAppName[] = TEXT("C:\\windows\\system32\\cmd.exe");
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL fSuccess;
LPSTR lpszVariable;
LPWCH lpvEnv;
lpvEnv = GetEnvironmentStrings();
if (lpvEnv == NULL)
{
std::cout << "GetEnvironmentStrings() Failed\n";
system("Pause");
return 0;
}
lpszCurrentVariable = lpvEnv;
if (FreeEnvironmentStrings(lpvEnv) != 0)
{
std::cout << "Freed block!\n";
}
if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, L"MyNewOwnEnvSetting=ver 2.0")))
{
system("Pause");
return 1;
}
lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, L"MyNewOwnVar=MyPath")))
{
std::cout << "StringCchCopy() - String copy #2 failed\n";
system("Pause");
return 1;
}
lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
*lpszCurrentVariable = (WCHAR)0;
SecureZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
fSuccess = CreateProcess(szAppName, L"C:\HFSS\setup_vars.bat", NULL, NULL, TRUE, NULL, (LPVOID)lpszCurrentVariable, NULL, &si, &pi);
DWORD ret = WaitForSingleObject(pi.hProcess, INFINITE);
system("Pause");
return 0;
}
I am not entire sure what the following lines are supposed to be doing:
if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, L"MyNewOwnEnvSetting=ver 2.0")))
{
system("Pause");
return 1;
}
lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, L"MyNewOwnVar=MyPath")))
{
std::cout << "StringCchCopy() - String copy #2 failed\n";
system("Pause");
return 1;
}
From Windows Dev-center
By default, a child process inherits the environment variables of its
parent process. Programs started by the command processor inherit the
command processor's environment variables. To specify a different
environment for a child process, create a new environment block and
pass a pointer to it as a parameter to the CreateProcess function.
Also: make sure your PATH variable doesn't exceed the maximum allowed size.