How to Remove Hex Digits Prepended to a Windows Process Name - c++

I have created a 64-bit executable using Visual Studio 2015, intended to be run on Windows 7. The executable is a C++ wrapper that calls the main method in a Java application via JNI. The application runs as expected, but in Windows Task Manager, on the "Process" tab, my application name has been prepended with 16 hex digits. So even though my application compiles to "someapp.exe", it is listed as "80005b29594d4a91someapp.exe" in the process list when I run it. Does anyone know why this is happening, and how to make it show up as just "someapp.exe" in the Task Manager?
EDIT 1:
I should note that the hex string is always the same when it appears in the name. However, there is a small percentage of the time I run my application when it actually has the expected name of "someapp.exe". I have not been able to figure out the pattern of when the hex string is prepended and when it is not, but I estimate the hex string appears 98% of the time it is executed.
EDIT 2:
This appears to be related somehow to the use of JNI. When I remove the JNI calls, this stops occuring altogether. The following represents the entirety of the C++ code making up the "someapp" application:
#include <jni.h>
#include <Windows.h>
#define STRING_CLASS "java/lang/String"
int main(size_t const argc, char const *const argv[]) {
// Modify the DLL search path
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32 |
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);
SetDllDirectoryA(R"(C:\Program Files\Java\jdk1.8.0_112\jre\bin\server)");
// Create and populate the JVM input arguments
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_8;
vm_args.ignoreUnrecognized = JNI_FALSE;
vm_args.nOptions = 2;
vm_args.options = new JavaVMOption[vm_args.nOptions];
// Set command-line options
vm_args.options[0].optionString = "-Dfile.encoding=UTF-8";
vm_args.options[1].optionString = "-Djava.class.path=someapp.jar";
// Create the JVM instance
JavaVM *jvm;
JNIEnv *env;
JNI_CreateJavaVM(&jvm, reinterpret_cast<void**>(&env), &vm_args);
// Get the main entry point of the Java application
jclass mainClass = env->FindClass("myNamespace/MainClass");
jmethodID mainMethod = env->GetStaticMethodID(
mainClass, "main", "([L" STRING_CLASS ";)V");
// Create the arguments passed to the JVM
jclass stringClass = env->FindClass(STRING_CLASS);
jobjectArray mainArgs = env->NewObjectArray(
static_cast<jsize>(argc - 1), stringClass, NULL);
for (size_t i(1); i < argc; ++i) {
env->SetObjectArrayElement(mainArgs,
static_cast<jsize>(i - 1), env->NewStringUTF(argv[i]));
}
env->CallStaticVoidMethod(mainClass, mainMethod, mainArgs);
// Free the JVM, and return
jvm->DestroyJavaVM();
delete[] vm_args.options;
return 0;
}
I have tried to remove the arguments passed to the Java main method, but that had no affect on the outcome.
EDIT 3:
Thanks to the suggestion from 1201ProgramAlarm, I realized that this was actually related to running from a dynamic ClearCase view. The "Image Path Name" column in the Task Manager was one of the following values, which directly correlates with the incorrect "Image Name" symptom that I was observing:
\view\view-name\someapp-path\someapp.exe
\view-server\views\domain\username\view-name.vws.s\00035\8‌​0005b29594d4a91somea‌​pp.exe
I would still like to know why this is happening, but since this only affects our development environment, fixing it has become low priority. For anyone else experiencing this problem, the following represents the relevant software installed in my environment:
Windows 7 Enterprise x64 SP1
Rational ClearCase Explorer 7.1.2.8
Visual Studio 2015 Update 3
Java x64 JDK 8u112

Run your application from a drive that isn't a ClearCase dynamic view.
The Image Name of the running process reference a file in a ClearCase view Storage (\\view\view-name\someapp-path\someapp.exe =>
\\view-server\views\domain\username\view-name.vws\.s\00035\8‌​0005b29594d4a91somea‌​pp.exe), the .vws meaning view storage.
See "About dynamic view storage directories":
Every view has a view storage directory. For dynamic views, this directory is used to keep track of which versions are checked out to your view and to store view-private objects
So a view storage exists both for snapshot and dynamic view.
But for dynamic view, that storage is also used to keep a local copy of the file you want to read/execute (all the other visible files are accessed through the network with MVFS: MultiVersion File System)
That is why you see \\view-server\views\domain\username\view-name.vws\.s\00035\8‌​0005b29594d4a91somea‌​pp.exe when you execute that file: you see the local copy done through MVFS by ClearCase.
Would you have used a snapshot view, you would not have seen such a complex path, since a snapshot view by its very nature does copy all files locally.
It appears as though the path is "correct" when I have not accessed the MVFS mount recently using Windows Explorer
That means the executable executed by Windows is still the correct one, while MVFS will be busy downloading that same executable from the Vob onto the inner folder of the view storage.
But once you re-execute it, that executable is already there (in the view storage), so MVFS will communicate its full path (again, in the view storage) to Windows (as seen in the Process Explorer)

Related

How can i attach a debugger to google v8?

In my application (Windows 10 VC2017) i enabled the possibility to write and execute scripts using google v8 and v8pp.
v8pp calls a script like this:
v8::Local<v8::Value> context::run_script(std::string const& source, std::string const& filename)
{
v8::EscapableHandleScope scope(isolate_);
v8::Local<v8::Context> context = isolate_->GetCurrentContext();
v8::ScriptOrigin origin(to_v8(isolate_, filename));
v8::Local<v8::Script> script;
bool const is_valid = v8::Script::Compile(context,
to_v8(isolate_, source), &origin).ToLocal(&script);
v8::Local<v8::Value> result;
if (!script.IsEmpty())
{
auto res1 = script->Run(context); //
if(! res1.IsEmpty())
result = res1.ToLocalChecked();
}
return scope.Escape(result);
}
How can i attach a debugger (chrome debug) to my code?
I found googles description at https://v8.dev/docs/inspector -
But this leaves some things blank and consists mostly of js code?
And i found the implementation for v8toolkit at https://github.com/xaxxon/v8toolkit/blob/master/src/debugger.cpp. But this seems to run not for windows.
What is a easy way to attach chrome debug to js code? The code is typically not a file but rather is stored in a data base and then stored in a std::string.
I finally got done a windows version of v8inspector that works well with my stand alone windows application with integrated v8.
I made a own fork including descriptions where to find/build the required 3rd party libraries (or where to find prebuilds). I also did a number of changes/additions:
https://github.com/StefanWoe/v8inspector
In the meanwhile this has also been merged into the parent project:
https://github.com/hsharsha/v8inspector
EDIT:
In the meanwhile ive been pointed to another implementation built with boost::beast and no other dependencies. Much simpler and more robust etc.:
https://github.com/ahmadov/v8_inspector_example

How to get localized names for Windows default folders in Qt

Using Qt, I can get some default path where I can create files via e. g. QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) which works fine on both Linux and Windows. I also saw that one can get a localized name for the respective location via QStandardPaths::displayName.
The "problem" is that, on Windows, the names of some default folders are displayed localized. For the above command, I get – according to the documentation – C:/Users/some_user/Documents. This is probably the actual path on the disk. But what the user (with a German locale) sees is a translated version: C:/Benutzer/some_user/Eigene Dokumente in this case.
So, not only the last folder is translated (the string I could get via the QStandardPaths::displayName call), but also the base directory.
Is there a reliable standard Qt way to be able to display the directory names the user knows from his other Windows programs?
It's not exactly what you are looking for but I think that can give an idea. You can get a default path by accessing to the Windows Environment Variables:
In C++ is really, we have a native function for that purpose:
inline auto get_environement_variable(const char* key ) {
char * val = getenv(key);
return (val == NULL) ? "" : std::string(val);
}
Some of the default environment variables:
auto programFiles = get_environement_variable("%ProgramW6432%");
auto programFilesX86 = get_environement_variable("%ProgramFiles(x86)%");
auto userProfile = get_environement_variable("%USERPROFILE%");
Maybe I'm wrong but I think that this is the one for the documents folder:
auto userProfile = get_environement_variable("%USERPROFILE%\Documents");
My OS is in English so I cannot confirm that the returned string is the translated one.

WPD Object Filename Truncated at '.'

In my project, I'm using the Windows Portable Device (WPD) API to enumerate the contents of a mobile device. WPD API Enumeration Guide. I'm able to enumerate over each object and view their properties as shown in the API programming guide. WPD API Properties Guide
However when I try to get an object's name that has a . within the name, the returned value is truncated at that .
HRESULT hr = objectProperties->GetStringValue(WPD_OBJECT_NAME, &strOriginalFileName);
if(FAILED(hr))
return false;
PWSTR wideStr = strOriginalFileName;
char buffer[20];
wcstombs(buffer, wideStr, 20);
qDebug() << buffer;
So for example, an object (folder on the device) with the name of com.example is returned as com. This becomes an obvious issue when I'm trying to locate a specific filepath on the device.
I can't seem to figure out what's wrong. Am I misunderstanding how the filename actually is? Is example another property or something within the com object? I'm very confused.
EDIT:
So I used the WPD API sample software to retrieve all the object properties of the com.example object and you can see that WPD itself cannot get the full folder name.
Thanks for your time!
The WPD Application Programming Reference refers following 3 NAMEs.
WPD_OBJECT_HINT_LOCATION_DISPLAY_NAME: A friendlier name, mostly intended for display
WPD_OBJECT_NAME: The name of the object on device.
WPD_OBJECT_ORIGINAL_FILE_NAME: The original filename of the object on device.
The MS code sample in C++ uses WPD_OBJECT_ORIGINAL_FILE_NAME to get to the actual file name (underneath the object) while transferring files from device to PC.
I modified the MS code sample (to enumerate object properties) and it showed me the actual file name (nothing truncated from the filename com.ef1.first.second)
I used:
Windows Windows 7 Ultimate (without SP1)
Visual Studio 2013
Android 4.4.4 (Moto-E)
Connection type: MTP
Memory type: Internal Memory as well as External (SD Card)
I wouldn't be surprised if it doesn't work on some combination of Windows versions, Windows SDK versions, android versions, Connection types (MTP, PTP, USB Mass Storage).
Here is the part of code that I modified (and that is how it worked).
// Reads properties for the user specified object.
void ReadContentProperties(_In_ IPortableDevice* device)
{
//.... Edited for brevity
tempHr = propertiesToRead->Add(WPD_OBJECT_NAME);
if (FAILED(tempHr))
{
wprintf(L"! Failed to add WPD_OBJECT_NAME to IPortableDeviceKeyCollection, hr= 0x%lx\n", tempHr);
}
// Here is the added code
tempHr = propertiesToRead->Add(WPD_OBJECT_ORIGINAL_FILE_NAME);
if (FAILED(tempHr))
{
wprintf(L"! Failed to add WPD_OBJECT_ORIGINAL_FILE_NAME to IPortableDeviceKeyCollection, hr= 0x%lx\n", tempHr);
}
//.... Edited for brevity
}

How does "send to" manages input arguments? (Windows)

Background: I want to add my application to the windows context menu, I have done this by adding a new key to the windows registry:
HKEY_CLASSES_ROOT\*\shell\myapp
HKEY_CLASSES_ROOT\*\shell\myapp\command
And assigning the default value of the "command" key to the location of my exe, plus an extra argument:
value = "c:\users\john\myapp\myappexe.exe" "%1" arg1
It works, i can 'right click' any file and run my application with that file. The problem comes when I try to select multiple files, it opens as many windows of my app as files selected, I want to be able to handle all the inputs with one instance of my program.
I'm aware that this may be solved by creating shell extensions as posted here, here, here or here. Creating a full functional shell extension is out of the scope of my (small) project, and I haven't found tutorials which I can understand.
Problem: I'm looking a way around it, and I found that a program called from the "send to" folder in windows is able to handle multiple files, for example, if i put the execulable of this code (c++) in the C:\Users\john\AppData\Roaming\Microsoft\Windows\SendTo folder,
#include <iostream>
using namespace std;
int main(int argc, char* argv[]){
for(int i=0;i<=argc;i++){
cout << argv[i] << endl;
}
return 0;
}
...select a bunch of flies, and drag them into the executable, I'll get in one window the path of all the selected files (send to tutorial). How does this work? Can I use this behavior and apply it to my app?
One approach is to design your application so that any newly launched instance checks for a pre-existing instance (you could use a mutex to do this) and then forwards the command-line parameters to that one, encapsulated in a message of some kind. The original instance can then take the appropriate action.

C++ How do we make our application start on computer startup (and of course, after a user signed in)?

How do we make our application start on computer startup (and of course, after the user had signed in)?
And no, I am not making a virus.
Does registry editing sound like a good idea?
My OS is Windows 8.
However, I will try to make my application available for all possible Window OS.
The correct way to do this is simply to add a shortcut to your application's executable to the user's Startup folder. You do not need to (and should not) modify the registry.
Advanced users know how to do this manually already, but it may also be an option you want to provide as part of your installer and/or a configuration dialog in your application.
To do this from C++ code, you will need to do two things:
Retrieve the location of the current user's Startup folder.
This is accomplished by calling the SHGetKnownFolderPath function and specifying the KNOWNFOLDERID of the folder you're interested in. In this case, that would be FOLDERID_Startup.
Sample code:
std::wstring GetStartupFolderPath()
{
PWSTR pszPath;
HRESULT hr = SHGetKnownFolderPath(&FOLDERID_Startup,
0, // no special options required
NULL, // no access token required
&pszPath);
if (SUCCEEDED(hr))
{
// The function succeeded, so copy the returned path to a
// C++ string, free the memory allocated by the function,
// and return the path string.
std::wstring path(pszPath);
CoTaskMemFree(static_cast<LPVOID>(pszPath));
return path;
}
else
{
// The function failed, so handle the error.
// ...
// You might want to throw an exception, or just return an
// empty string here.
throw std::runtime_error("The SHGetKnownFolderPath function failed");
}
}
Note, however, that while SHGetKnownFolderPath is the recommended function to use, it is supported only by Windows Vista and later. If you need to support older versions of the operating system, you'll need to call it dynamically on newer versions where it is available, and otherwise fall back to calling the SHGetFolderPath function. This one takes a different type of identifier, a CSIDL value. The one you want is CSIDL_STARTUP.
Create a shortcut to your application's executable.
This is accomplished using a different set of Shell API functions. I won't bother writing up sample code here because it's all quite well explained on MSDN already: Shell Links
Now you just connect the dots: when you create the shortcut to your application's executable, specify the user's Startup folder as its destination path.
The only other thing to be aware of is that there are actually multiple Startup folders. Each user has one, which is the one we retrieved above using FOLDERID_Startup. About 99% of the time, that's the one you want. Putting a shortcut to your app there will cause it to be launched automatically when that user logs on.
However, there is also a global Startup folder that is shared by all users. This one is identified by FOLDERID_CommonStartup (or CSIDL_COMMON_STARTUP) and requires administrative privileges to add items to. That makes sense, of course, because whatever you put in there is going to launch automatically when any user logs on to the computer. Only administrators can affect global behavior like this. And chances are, your app doesn't need this anyway.
Start menu
Simplest solution is to place .lnk of .bat file into the Start Menu\On startup folder. This is easiest and not too sneaky against the user.
Registry:
Another solution is creating the key in the registry keys:
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run] //All users
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce] //All users once
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run] //Currend user
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce] //Current user once
This is not that transparent - so a bit more agressive against the user.
On windows you can put a shortcut to your application in the Startup folder, or you can implement it as a service.
And that "I am not making a virus" does make you sound guilty... Maybe it is a keylogger? ;)
There are a lot of ways, but they all depend on your OS. For windows take a look at the "Task Schedualer" under "Administrative tools" in the control panel.
Maybe something like this? Note, this code snippet is not written by me.
#include <windows.h>
void Reg() {
::HKEY Handle_Key = 0;
::DWORD Dispoition = 0;
::RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
0,
KEY_ALL_ACCESS,
&Handle_Key );
const unsigned char Path[ MAX_PATH ] = "C:\\Windows\\YourProgramName.exe";
::RegSetValueEx( Handle_Key, "My Directory", 0, 1, Path, sizeof( unsigned char ) );
};
What do you guys think?