I am setting up a scratch desktop to run another application in a "silent mode" - the other app is noisy and throws all sorts of windows around while it processes.
I have used the info here: CreateDesktop() with vista and UAC on (C, windows)
and CreateDesktop works - I can create the other desktop, I can launch the application into the other desktop (I see it launching in task manager) - but when I try to interact with the app via DDE, the DdeConnect call hangs until it times out.
And here's how I'm calling CreateDesktop:
LPSTR desktopName = "MYDESKTOPNAME";
HDESK hDesk = CreateDesktop(desktopName , NULL, NULL, 0, DESKTOP_SWITCHDESKTOP|
DESKTOP_WRITEOBJECTS|
DESKTOP_READOBJECTS|
DESKTOP_ENUMERATE|
DESKTOP_CREATEWINDOW|
DESKTOP_CREATEMENU, NULL);
Here is CreateProcess to actually launch the app into the new desktop:
STARTUPINFO startupInfo;
GetStartupInfo(&startupInfo);
startupInfo.lpDesktop = desktopName;
PROCESS_INFORMATION procInfo;
memset(&procInfo, 0, sizeof(procInfo));
if (CreateProcess(NULL, exePath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &procInfo)){
WaitForInputIdle(procInfo.hProcess, INFINITE);
CloseHandle(procInfo.hProcess);
CloseHandle(procInfo.hThread);
}
If it matters, the call to DdeInitialize:
DWORD afCmd = APPCLASS_STANDARD | APPCMD_CLIENTONLY | CBF_SKIP_ALLNOTIFICATIONS;
UINT rslt = ::DdeInitialize(&ddeInst, NULL, afCmd, 0);
Here is the DdeConnect call (the hsz* parameters, etc... are all fine - if I launch the app into the regular desktop, the calls all work perfectly).
hConv = ::DdeConnect(ddeInst,
hszService,
hszTopic,
NULL);
This call just hangs for ~60 seconds.
Is this a security issue of some sort? i.e. the windows messages aren't passing between desktops? Or does anyone have any suggestion on how to troubleshoot this further?
The documentation for CreateDesktop contains a cross-reference to the Desktops topic, which says
Window messages can be sent only between processes that are on the same desktop.
The overview topics are important. They provide background information to help you understand the feature.
Raymond explains why the messages don't get through. In order to solve the problem, assuming you continue with the separate desktop, you will simply need to run the process that performs the DDE in the same desktop as the target app. If you need to communicate between your process on the main desktop and the target process then you will need to use some other form of IPC.
Related
I have a small winmain application.
It is a winmain because I don't want it to flash a console at startup.
But if it is launched from a console, I would like to print in this console.
Is this possible ?
As noted by eryksun in the comments, AttachConsole is not perfect because cmd.exe only waits for console applications.
A sneaky workaround is to have a little console helper .exe that you rename to .com. It sits between you and the parent console application. You still need to use AttachConsole or DuplicateHandle to get access to the console handles in the GUI application...
here is the solution I've retained:
if ( AttachConsole(ATTACH_PARENT_PROCESS) )
{
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
int fd = _open_osfhandle((intptr_t)hStdOut, _O_TEXT);
if (fd > 0) *stdout = *_fdopen(fd, "w");
}
CreateFile() returns ACCESS_DENIED in Windows10 when i try in my project. If i create sample application using CreateFile() it works fine. Even tried to check admin privileges before calling CreateFile(), user is in admin mode. Same code works fine in Win 7.
Below is code sample:
WCHAR userPath[] = L"C:\\test.txt";
HANDLE hFile = NULL;
hFile = ::CreateFile(userPath,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
wprintf(L"Error HANDLE = 0x%x \n",hFile);
}
else
{
wprintf(L"Suceess HANDLE = 0x%x \n",hFile);
::CloseHandle(hFile);
}
The most obvious explanation is that your user simply does not have sufficient rights to create files at the root level of the system drive.
Since Windows 7, and possibly even Vista, the default security configuration of the system drive permits standard user to create folders at the root level, but not files. So, my hypothesis is that you are not running your process elevated as you claim, but are in fact running the process with standard user rights. In order for you to create a file at that location you will need to either:
Run the process with elevated rights, or
Modify the security settings of the volume.
I was running my application in browser. There was issue with IE settings. When i disabled protected mode from IE->Security->Enable protected Mode, CreateFile() worked. Another solution is adding the ip to trusted site in IE.
I know the Brew application have 3 types: active, suspend & background. Launch one BREW application as active or suspend is very simple. I know in BREW2.0 and later version, there is a new application type can allow we create one application in the background. It will not stay in the application stack and change status by active or resume command. It will always stay in the background no matter what user command system received. In one of my small project, I need to create and launch one background application like this.
Unfortunately, I cannot find a simple example on Qualcomm or Google. Is there any programmer who has encountered the same problem?
Yes, you are right. BREW2.0+ do support background application.
When we initial a background application, just like other normal new application, it can be launched by the brew application interface directly. You also can launch it by ISHELL_StartApplet function.
When you want to put one brew application in the background, you need do it when handle EVT_APP_STOP event and must set dwParam to false. After handling EVT_APP_STOP by this, the application will be put in the background. And if you want to change it to normal application, you need call ishell_StartApplet function to active to itself again.
Example code:
typedef struct _bgApp
{
AEEApplet a;
boolean m_bGoBg;
} bgApp;
switch (eCode)
{
case EVT_APP_START:
if(pMe->m_bGoBg)
ISHELL_CloseApplet(pMe->a.m_pIShell, FALSE);
case EVT_APP_STOP:
if(pMe->m_bGoBg)
*((boolean*) dwParam) = FALSE;
return TRUE;
case EVT_USER:
if(pMe->m_bGoBg)
{
pMe->m_bGoBg = FALSE;
// make applet active
ISHELL_StartApplet(pMe->a.m_pIShell, AEECLSID_BGAPP); }
else
{
pMe->m_bGoBg = TRUE;
// trigger EVT_APP_STOP to send app to background
ISHELL_CloseApplet(pMe->a.m_pIShell, FALSE);
}
return TRUE;
}
There is a limitation of background application. You cannot change the screen or communicate with user directly. Developer should be careful on the memory used by the background application. This is very important.
I have created a Credential Launcher for Windows 7 and was able to run Windows application after the Tile button click event, it was very easy.
I added a few registry settings and *pbAutoLogon = FALSE;.
However now i am now trying to do the same for Windows XP.
Which function I should target or how to achieve the same results ?
I see you tagged your question with "Gina", so I guess you know that Credential Providers do not exist on XP.
Your answer depends on when exactly you want to run that program, especially with regards to the secure attention sequence (SAS, or when a user press CTRL-ALT-Delete)
Before the SAS, use WlxDisplaySASNotice
After the SAS, use WlxLoggedOutSAS
Since you don't want to write a whole GINA yourself, you could use a custom Gina that wraps msgina.dll. Here is one I wrote, you can find the original I started from in the Platform SDK.
Using that approch, you get a chance to execute code just before or just after certain events, like running your program after a successful logon, something like :
int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType, PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID * pProfile)
{
int result;
result = pfWlxLoggedOutSAS(pWlxContext, dwSasType, pAuthenticationId, pLogonSid, pdwOptions, phToken, pMprNotifyInfo, pProfile);
if (result == WLX_SAS_ACTION_LOGON)
{
//We have a successful logon, let's run our code
run_my_custom_code();
}
return result;
}
There are some caveats, though :
The code cannot block. Winlogon will wait, but your users might not. Spanw a process and let it run.
Your program will be running with SYSTEM privileges, which is a security risk. Sandboxing your process could be hard. If you can't break out of it, don't assume nobody can...
HI,
Im using Delphi and I want to make an application that can do the following
When started from within Terminal services (remote desktop), if another user logs into another terminal services session they should be able to see the application running in the desktop tray. However if a user sitting at the server logs in then they shouldn't see the application running in the desktop tray. Its fine if everyone can see it running in the process list, just not the desktop tray.
How can I do this?
Make your application launch on startup on every user, then use this function to determine whether to quit or not:
#include <windows.h>
#include <winternl.h>
BOOL IsRunningOnTerminalServerClient( void )
{
PWINSTATIONQUERYINFORMATIONW WinStationQueryInformationW;
WINSTATIONINFORMATIONW wsInfo;
HINSTANCE hInstWinSta;
ULONG ReturnLen;
hInstWinSta = LoadLibraryA( "winsta.dll" );
if( hInstWinSta )
{
WinStationQueryInformationW = (PWINSTATIONQUERYINFORMATIONW)
GetProcAddress( hInstWinSta, "WinStationQueryInformationW" );
if( WinStationQueryInformationW &&
WinStationQueryInformationW( SERVERNAME_CURRENT,
LOGONID_CURRENT,
WinStationInformation,
&wsInfo,
sizeof(wsInfo),
&ReturnLen ) &&
( wsInfo.LogonId != 0 ) )
{
FreeLibrary( hInstWinSta );
return( TRUE );
}
FreeLibrary( hInstWinSta );
}
return FALSE;
}
Pulled from http://msdn.microsoft.com/en-us/library/aa383827(v=VS.85).aspx
Assumption: You are logging into a Windows Server - two people cannot RDP at the same time on the Desktop OSes. My experience with this is that you should not see applications running visually - ie on the desktop or on the taskbar or tray icon area.
If you go into the task manager and look at the processes running - you may see process running. Also, if you are Administrator, then you may "Kill" the process, else there is nothing you can do with it.
Does this help?
Please clarify what you are asking.