program exits when shellexcute was called - winapi

win7 OS, vs2008.
My program disappears when shellexcute was called,
It's a WTL project and the code like these:
*.h
COMMAND_HANDLER(IDC_BTN_LOGIN, BN_CLICKED, DoLogin)
*.cpp
LRESULT XLoginView::DoLogin(WORD, WORD, HWND, BOOL&)
{
::ShellExecute(NULL, _T("open"), _T("http://mysite.com/login.php"), NULL,NULL, SW_SHOW);
return 0;
}
when the login button was clicked, then my program was disappeard and the visual studio exit too.
Even the code is such simple as these:
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
ShellExecute(NULL, L"open", L"http://stackoverflow.com", NULL, NULL, SW_SHOW);
}
return nRetCode;
}
The site (http://stackoverflow.com) was openned only the first running or debugging, then the second time and over, the visual studio disappears at the same time.
Here is a same problem, but didn't give the reason
http://bbs.pediy.com/showthread.php?t=130968
update 2013-08-27
As IInspectable's suggestion, it works ok with local resource, but web resource.
Google Chrome is my default browser, so I trust some other browsers as default browser, then get these result below:
(1) Default browser: Google Chrome
If I directly run my program, it is ok, it works. The web resource(URL) was openned, the program doesn't crush.
But if I debug the program from visual studio's button "start debugging", not only the program exit but also visual studio exit when the button who's event code calls "ShellExcute".
(2) Default browser: Firfox or Internet Explorer
The program works, it doesn't crush or disappear whenever I run it directly or debug it from visual studio.
As the above I think maybe it's because the program's Privilege is not enough.
so I trust the code below, then the problem disappeared.
void UpPrivilege()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
LookupPrivilegeValue(NULL, L"SeDebugPrivileges", &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0);
}

update 2013-08-27
As IInspectable's suggestion, it works ok with local resource, but web resource.
Google Chrome is my default browser, so I trust some other browsers as default browser, then get these result below:
(1) Default browser: Google Chrome
If I directly run my program, it is ok, it works. The web resource(URL) was openned, the program doesn't crush.
But if I debug the program from visual studio's button "start debugging", not only the program exit but also visual studio exit when the button who's event code calls "ShellExcute".
(2) Default browser: Firfox or Internet Explorer
The program works, it doesn't crush or disappear whenever I run it directly or debug it from visual studio.
As the above I think maybe it's because the program's Privilege is not enough.
so I trust the code below, then the problem disappeared.
void UpPrivilege()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
OpenProcessToken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
LookupPrivilegeValue(NULL, L"SeDebugPrivileges", &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0);
}

Related

Firefox Native Messaging runtime.LastError not giving any errors in case of no Native application installed on Connectnative

I am trying to check whether the Native app is installed or not , If it is not I have to prompt the user to download it from the webpage. For chrome I used to achieve by checking the error messages from runtime.LastError. However in case of Firefox it gives error only in console No such native application extension_name and not catching it in the runtime.LastError method.
Is there any way that we can identify whether corresponding Native app is installed or not ?
I am facing issue when Native app is not installed and browser.runtime.lastError is not giving any error.
Can you please suggest if there is any way in Firefox Webextension that we can catch such errors and identify it in code whether the corresponding Native app is installed or not on the user machine.
It will really helpful if someone can provide some info on this.
for e.g. :
startNativeApp: function(force){
// note that when the native app is opened and ready, it will call "_ABC_onAgentReady"
ABC.log('Starting native app.');
if (!ABC.appConnected) {
try {
ABC.nativeAppPort = browser.runtime.connectNative(_ABC_native_app_id);
ABC.nativeAppPort.onMessage.addListener(ABC.onNativeMessageReceived);
ABC.nativeAppPort.onDisconnect.addListener(ABC.onNativeAppDisconnected);
ABC.appInstalled = true;
ABC.appConnected = true;
} catch(e) {
ABC.log('Error starting native app: ' + e.message, 'ERR');
}
} else if (force === true) {
ABC.log('Native app is already running; attempting to stop and will restart in 750ms.');
ABC.stopNativeApp();
setTimeout(function() { ABC.startNativeApp(true); }, 750);
}
},
onNativeAppDisconnected: function(message) {
console.log("ABC LastError : "+browser.runtime.lastError);
console.log("ABC LastError : "+ABC.nativeAppPort.error);
console.log("ABC LastError : "+JSON.stringify(message));
ABC.appConnected = false;
ABC.nativeAppPort = null;
ABC.appInstalled = false;
if (browser.runtime.lastError && (browser.runtime.lastError.message.indexOf("No such native application") !== -1 )) {
ABC.appInstalled = false;
}
// cleanup: reset the sig data so that it is re-requested on the next scan
_ABC_sa_data = "";
_ABC_sigs = "";
if (browser.storage && browser.storage.local) {
browser.storage.local.set({ uid: _ABC_be_uid }, null);
}
ABC.log('Send message to page to stop.');
ABC.sendMessageToPage({ onNativeAppDisconnected: '' });
ABC.log('Native app disconnected.');
},
Issue here was that port.error was not giving any error response in Firefox versions less than 52 , Due to which I was facing problem in identifying whether native app is installed or not.
After discussion on Mozilla Community (https://discourse.mozilla-community.org/t/firefox-native-messaging-runtime-lasterror-not-giving-any-errors-in-case-of-no-native-application-installed-on-connectnative/12880/4) , we found that it is actually missed and a bug is already reported : https://bugzilla.mozilla.org/show_bug.cgi?id=12994116
which will be resolved in Firefox 52.
However , I need to support Firefox 50 also , so the alternate I am using is to call native application in starting to find out whether it is installed or not.
If I got back response than it is installed otherwise it is not.
However specific error messages will be available from Firefox52.
Right now at chrome 109 the following approaches won't work after connectNative:
chrome.runtime.lastError. The error is printed because it is visible in the log but right after the call it is undefined.
console.error = function (arg) {/**/}. Is not working to replace the default function.
port.name is "" in both cases (error or no error).
port.onDisconnect is not called if the application is missing.
The only solution left is to call a third checker:
const promise=chrome.runtime.sendNativeMessage("appname", { /*text: ""*/ });//,check_response
promise.then(check_response,check_error);
In Firefox there is no runtime.lastError.
The listener function you pass to runtime.Port.onDisconnect isn't passed the message, it's passed the port itself.
You then want port.error.
See the documentation for onDisconnect here https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/runtime/Port

OpenMutex fails in process opened with CreateProcessAsUser

I've been banging my head on this for days, and I must have read every page on the Internet even remotely related, but I still can't find an answer. Help!
Here's the scenario: In Windows 7, I have a process running under an admin user account (not a service). It creates a global named mutex, which is later used in a child process running under a regular user account. No matter what I do, or what ACLs I put on the mutex, the child process keeps returning Access Denied when trying to get the handle.
I've distilled my code down into a test app just to experiment with the process and mutex parts, and I found something surprising: if I call OpenMutex from the user app without first creating the mutex, I would expect a Not Found error but I still get Access Denied. However, if I launch the user app from Explorer instead (shift-right-click, Run as different user...), I get the expected behavior. I also noticed that the user app has a plain blocky window border rather than the normal Windows theme when launched from the admin app.
So my guess is that there's something wrong with how I'm launching the user app, but I just can't see what I'm missing.
Here are the relevant parts:
bool CUserTest::LogInUser()
{
if ((m_hUserToken == NULL) && !LogonUser(TEST_USER_NAME, L".", TEST_USER_PASS, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &m_hUserToken))
{
CloseHandle(m_hUserToken);
m_hUserToken = NULL;
}
return (m_hUserToken != NULL);
}
bool CUserTest::LaunchTestApp()
{
PROCESS_INFORMATION ProcInfo;
STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(si);
si.lpDesktop = L"winsta0\\default";
wchar_t wszCmdLine[MAX_PATH + 1] = { 0 };
wcscpy(wszCmdLine, L"UserTestClient.exe");
bool bSuccess = false;
LPVOID pEnv;
PROFILEINFO sProfileInfo;
ZeroMemory(&sProfileInfo, sizeof(PROFILEINFO));
sProfileInfo.dwSize = sizeof(PROFILEINFO);
sProfileInfo.lpUserName = TEST_USER_NAME;
if (LoadUserProfile(m_hUserToken, &sProfileInfo))
{
if (ImpersonateLoggedOnUser(m_hUserToken))
{
if (CreateEnvironmentBlock(&pEnv, m_hUserToken, FALSE))
{
bSuccess = CreateProcessAsUser(
m_hUserToken,
NULL,
wszCmdLine,
NULL, // ProcessAttributes
NULL, // ThreadAttributes
FALSE, // InheritHandles
CREATE_UNICODE_ENVIRONMENT, // CreationFlags
pEnv, // Environment
NULL, // CurrentDirectory
&si,
&ProcInfo); // ProcessInformation
DestroyEnvironmentBlock(pEnv);
}
RevertToSelf();
}
UnloadUserProfile(m_hUserToken, sProfileInfo.hProfile);
}
if (bSuccess)
{
CloseHandle(ProcInfo.hThread);
CloseHandle(ProcInfo.hProcess);
}
return bSuccess;
}
I never could get the CreateProcessAsUser call to work correctly, but I finally got it working using CreateProcessWithLogonW instead. The trick was to set si.lpDesktop to NULL rather than "winsta0\default", contrary to everything I'd read up to this point.

Calls to a COM Server succeed under administrator account but fail under SYSTEM account

I am trying to query some data from a COM server (actually the Motorola MeshAPI), but it fails to initialize. Using the code snippet below, I get successful data when running on the command line as Administrator, but my actual program using this code runs as a service under the SYSTEM account. Using "psexec -i -s cmd.exe" I ran the snippet under the SYSTEM account, and I get the same errors I saw with the service.
It is the CreateInstance() call that fails, with an error message "Server execution failed" and error code 2148007941 (0x80080005).
Under the Windows Event Viewer, in the System pane I see errors with source "DCOM", event ID 10010, and description "The server {....GUID} did not register with DCOM within the required timeout."
I've tried the tips from this answer https://stackoverflow.com/a/1157331 , but I haven't found anything helpful in solving this.
What would cause this to work under Administrator but fail under SYSTEM, and how can I get it to work when running under SYSTEM?
HRESULT hr=S_OK;
USHORT nLinkResistance;
if (!m_MeshNetInitialised)
{
hr = m_pApiCardInterface.CreateInstance("MeshAPI.MeshNet");// mea interface smart pointer
if (SUCCEEDED(hr))
{
Sleep(1000);
m_MeshNetInitialised = true;
}
}
if (m_MeshNetInitialised)
{
hr = m_pApiCardInterface->GetIAPLinkResistance(&nLinkResistance);
if( SUCCEEDED(hr) )
{
l_retval = nLinkResistance;
}
else
{
std::wcout << L"Error getting IAPLinkResistance" << std::endl;
}
}
if (FAILED(hr))
{
_com_error err(hr);
std::wcout << err.ErrorMessage();
}

How can I add customized strings to the messages displayed by shutdown screen in Windows 7?

How can I add custom text to shutdown screen, like those messages that show when Windows is installing updates before shutting down? For example, you have a backup script that is executed on shutdown, and you want to inform about the progress of the backup just like Windows does when installing updates. Is there any command line tool for that, or some code library, or even something in Windows API?
Note that this is not about how to shutdown a computer, and it is not about whatever way to display a message there in shutdown screen, such as console applications or message boxes. This is not about customizing existing messages either, and it is not about any shutdown dialog that shows before shutdown screen and allows the user to cancel the shutdown or proceed without waiting for the programs to terminate.
This is about understanding how Windows implements the displaying of those messages the way they are displayed there in shutdown, and how to add new messages to be displayed, preferably with progress information. To be clear, below is a screenshot.
There is a function WmsgPostNotifyMessage in wmsgapi.dll which is displaying this message. Undocumented though, but shouldn't be a problem to use.
Here is a C++ code that can shutdown the computer with message.
#include <windows.h>
#pragma comment( lib, "advapi32.lib" )
BOOL MySystemShutdown( LPTSTR lpMsg )
{
HANDLE hToken; // handle to process token
TOKEN_PRIVILEGES tkp; // pointer to token structure
BOOL fResult; // system shutdown flag
// Get the current process token handle so we can get shutdown
// privilege.
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return FALSE;
// Get the LUID for shutdown privilege.
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
&tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1; // one privilege to set
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// Get shutdown privilege for this process.
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
(PTOKEN_PRIVILEGES) NULL, 0);
// Cannot test the return value of AdjustTokenPrivileges.
if (GetLastError() != ERROR_SUCCESS)
return FALSE;
// Display the shutdown dialog box and start the countdown.
fResult = InitiateSystemShutdown(
NULL, // shut down local computer
lpMsg, // message for user
30, // time-out period, in seconds
FALSE, // ask user to close apps
TRUE); // reboot after shutdown
if (!fResult)
return FALSE;
// Disable shutdown privilege.
tkp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
(PTOKEN_PRIVILEGES) NULL, 0);
return TRUE;
}

Open local html file with parameters in default broswer on windows

I need to open html file on disk with parameters from within my C++ program in default browser.
For example: c:\index.html?id=15 .
I am using ShellExecute, to open all urls or files, but this one does not work, it strips parameters from local files.
ShellExecute(0, NULL, "file:///c:\index.html?id=15", NULL, NULL, SW_SHOWNORMAL);
It works fine from command line i.e.
iexplore file:///c:\index.html?id=15
How can I open that page?
Please try this code.
int result = 0;
TCHAR app[MAX_PATH] = { 0 };
result = (int)::FindExecutable(_T("C:\\index.html"), NULL, app);
if (result > 32) {
::ShellExecute(0, NULL, app,
_T("file:///C:\\index.html?id=15"), NULL, SW_SHOWNORMAL);
}

Resources