cc16
asked on
Hooking the Logon Desktop (Windows C++)
Hello
Is it possible to install a hook in the windows login desktop?
So far, I have built a windows service which means the program can remain running after the user has logged off. However i do not know how to hook the login desktop.
Note, this research is strictly only for educational/experimental purposes.
Any help would be much appreciated,
Southern Curriez
Is it possible to install a hook in the windows login desktop?
So far, I have built a windows service which means the program can remain running after the user has logged off. However i do not know how to hook the login desktop.
Note, this research is strictly only for educational/experimental purposes.
Any help would be much appreciated,
Southern Curriez
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
That's why you first just log them all - so you can see what the machine looks like before logon and after logon. It's also a good exercize just to have coded a full enumeration.
Under XP after logon, you may find a desktop called "Winlogon". Within that desktop, you'll find one of the windows:
* "Windows Security" - what you see when you CTRL/ALT/DEL
* "Computer Locked" - what you see when you lock the workstation
* "Unlock Computer" - the window to enter a password to unlock the workstation
Alas, I don't recall the XP logon window name, but you should see it in your enumeration log.
In your service, do a full enumeration, say, every 30 seconds, making sure you include a time stamp with each full enumeration. Then boot and wait one minute after the logon screen comes up before entering you info, and wait another minute after the box settles down before stopping the service and examining the enumeration log. It will be fairly easy to identify therein the name of the logon station, desktop, and window.
Under XP after logon, you may find a desktop called "Winlogon". Within that desktop, you'll find one of the windows:
* "Windows Security" - what you see when you CTRL/ALT/DEL
* "Computer Locked" - what you see when you lock the workstation
* "Unlock Computer" - the window to enter a password to unlock the workstation
Alas, I don't recall the XP logon window name, but you should see it in your enumeration log.
In your service, do a full enumeration, say, every 30 seconds, making sure you include a time stamp with each full enumeration. Then boot and wait one minute after the logon screen comes up before entering you info, and wait another minute after the box settles down before stopping the service and examining the enumeration log. It will be fairly easy to identify therein the name of the logon station, desktop, and window.
ASKER
for some annoying reason GetWindowText dosnt seem to work when called from this service...
should i just use the only window in Winlogon, or would a global hook work (a global hook would be easier)
here is what it looks like before i log in:
NEW WINDOW STATION: WinSta0
New Desktop: Default
New Desktop Window: 0x000B0050
New Desktop: Disconnect
New Desktop: Winlogon
New Desktop Window: 0x000C0052
NEW WINDOW STATION: Service-0x0-3e7$
New Desktop: WinSta0
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e7$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e4$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e5$
New Desktop Window: 0x000B0050
New Desktop: SAWinSta
New Desktop Window: 0x000B0050
NEW WINDOW STATION: Service-0x0-3e4$
New Desktop: WinSta0
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e7$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e4$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e5$
New Desktop Window: 0x000B0050
New Desktop: SAWinSta
New Desktop Window: 0x000B0050
NEW WINDOW STATION: Service-0x0-3e5$
New Desktop: WinSta0
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e7$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e4$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e5$
New Desktop Window: 0x000B0050
New Desktop: SAWinSta
New Desktop Window: 0x000B0050
NEW WINDOW STATION: SAWinSta
New Desktop: SADesktop
New Desktop Window: 0x000B0050
should i just use the only window in Winlogon, or would a global hook work (a global hook would be easier)
here is what it looks like before i log in:
NEW WINDOW STATION: WinSta0
New Desktop: Default
New Desktop Window: 0x000B0050
New Desktop: Disconnect
New Desktop: Winlogon
New Desktop Window: 0x000C0052
NEW WINDOW STATION: Service-0x0-3e7$
New Desktop: WinSta0
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e7$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e4$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e5$
New Desktop Window: 0x000B0050
New Desktop: SAWinSta
New Desktop Window: 0x000B0050
NEW WINDOW STATION: Service-0x0-3e4$
New Desktop: WinSta0
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e7$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e4$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e5$
New Desktop Window: 0x000B0050
New Desktop: SAWinSta
New Desktop Window: 0x000B0050
NEW WINDOW STATION: Service-0x0-3e5$
New Desktop: WinSta0
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e7$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e4$
New Desktop Window: 0x000B0050
New Desktop: Service-0x0-3e5$
New Desktop Window: 0x000B0050
New Desktop: SAWinSta
New Desktop Window: 0x000B0050
NEW WINDOW STATION: SAWinSta
New Desktop: SADesktop
New Desktop Window: 0x000B0050
Do you create the service with:
CreateService(...
,...
,..
,SERVICE_ALL_ACCESS
,SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCES S
,SERVICE_AUTO_START
,SERVICE_ERROR_NORMAL
,...
,null
,0
,null
,null
,null);
,SERVICE_ALL_ACCESS
,SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCES S
,SERVICE_AUTO_START
,SERVICE_ERROR_NORMAL
CreateService(...
,...
,..
,SERVICE_ALL_ACCESS
,SERVICE_WIN32_OWN_PROCESS
,SERVICE_AUTO_START
,SERVICE_ERROR_NORMAL
,...
,null
,0
,null
,null
,null);
,SERVICE_ALL_ACCESS
,SERVICE_WIN32_OWN_PROCESS
,SERVICE_AUTO_START
,SERVICE_ERROR_NORMAL
ASKER
i wasnt using CreateService...
is
ServiceStatus.dwServiceTyp e = SERVICE_ALL_ACCESS | SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCES S | SERVICE_AUTO_START | SERVICE_ERROR_NORMAL;
ok?
is
ServiceStatus.dwServiceTyp
ok?
ASKER
Oh i get it... CreateService is to put the service into the database...
ASKER
Ok I added it to the DB using CreateService.
Now GetWindowText returns ÝÝÝÝÝ each time (the length of the Ý string varies). I also couldnt help noticing that Ý is 11111111 in binary.
Anyways i dont think GetWindowText is so important.
The important thing is do I hook the only window in Winlogon, or should i use a global hook, or what?
Now GetWindowText returns ÝÝÝÝÝ each time (the length of the Ý string varies). I also couldnt help noticing that Ý is 11111111 in binary.
Anyways i dont think GetWindowText is so important.
The important thing is do I hook the only window in Winlogon, or should i use a global hook, or what?
I'll post some code later this weekend.
As far as the eventual hook is concerned, I believe it would have to be global. A hook is either for a single thread or for all threads, and I believe GINA may very well have several threads to worry about. With the global hook, you're not realy concerned with any specific thread, rather you'll want to see the messages associated with the specific window.
As far as the eventual hook is concerned, I believe it would have to be global. A hook is either for a single thread or for all threads, and I believe GINA may very well have several threads to worry about. With the global hook, you're not realy concerned with any specific thread, rather you'll want to see the messages associated with the specific window.
Slight delay - I lost a drive.
Should have everything rebuilt by tomorrow.
Should have everything rebuilt by tomorrow.
Here's some straight C code you can use to enumerate stations, desktops, and windows.
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winbase.h>
#include <winsvc.h>
#include <process.h>
#include <shellapi.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
BOOL CALLBACK EnumWindowStaCallback(LPTS TR,LPARAM) ;
BOOL CALLBACK EnumDesktopCallback(LPTSTR ,LPARAM);
BOOL CALLBACK EnumWindowsCallback(HWND,L PARAM);
void PutMSG(char*);
char MyFullName[512];
char LOGFile[512];
char EXEFile[512];
////////////////////////// ////////// ////////// ////////// ////////// //////////
////////////////////////// ////////// ////////// ////////// ////////// ////////// main
////////////////////////// ////////// ////////// ////////// ////////// ////////// /////
void main(int argc ,char * argv[])
{
int RC;
char ts[512];
// Get our full name
GetModuleFileName(NULL,MyF ullName,51 1);
sprintf(EXEFile,"%s",MyFul lName);
// Put the log file in the same directory
MyFullName[strlen(MyFullNa me)-4]='\0 ';
sprintf(LOGFile,"%s.log",M yFullName) ;
RC=EnumWindowStations(Enum WindowStaC allback,0) ;
return;
}
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
////////////////////////// ////////// ////////// ////////// ////////// ////////// / EnumWindowStaCallback
////////////////////////// ////////// ////////// ////////// ////////// ////////// ////////// ////////// ///
BOOL CALLBACK EnumWindowStaCallback(char * StationName,LPARAM lParam)
{
char ts[512];
HWINSTA hstation;
BOOL RC;
// Say who we found
PutMSG(" ");
sprintf(ts,"Station: <%s>",StationName);
PutMSG(ts);
// Enumerate this station's desktops
hstation=OpenWindowStation (StationNa me,true,ST ANDARD_RIG HTS_REQUIR ED
|WINSTA_ACCESSGLOBALATOMS
|WINSTA_ENUMDESKTOPS
|WINSTA_ENUMERATE
|WINSTA_READATTRIBUTES
|WINSTA_READSCREEN);
if (hstation==NULL)
{
sprintf(ts,"OpenWindowStat ion failure(%d)",GetLastError( ));
PutMSG(ts);
return true;
}
RC=EnumDesktops(hstation,E numDesktop Callback,l Param);
if (!RC)
{
sprintf(ts,"EnumDesktops failure(%d)",GetLastError( ));
PutMSG(ts);
}
CloseWindowStation(hstatio n);
return true;
}
////////////////////////// ////////// ////////// ////////// ////////// /
////////////////////////// ////////// ////////// ////////// ////////// / EnumDesktopCallback
////////////////////////// ////////// ////////// ////////// ////////// ////////// ////////// /
BOOL CALLBACK EnumDesktopCallback(LPTSTR DesktopName,LPARAM lParam)
{
char ts[512];
HDESK hdesktop;
BOOL RC;
// Say who we found
sprintf(ts," Desktop: <%s>",DesktopName);
PutMSG(ts);
// Enumerate this desktop's windows
hdesktop=OpenDesktop(Deskt opName,0,t rue,DESKTO P_ENUMERAT E|DESKTOP_ READOBJECT S);
if (hdesktop==NULL)
{
sprintf(ts," OpenDesktop failure(%d)",GetLastError( ));
PutMSG(ts);
return true;
}
RC=EnumDesktopWindows(hdes ktop,EnumW indowsCall back,lPara m);
if (!RC)
{
sprintf(ts," EnumWindows failure(%d)",GetLastError( ));
PutMSG(ts);
}
CloseDesktop(hdesktop);
return true;
}
////////////////////////// ////////// ////////// ////////// ////////// /
////////////////////////// ////////// ////////// ////////// ////////// / EnumWindowsCallback
////////////////////////// ////////// ////////// ////////// ////////// ////////// ////////// /
BOOL CALLBACK EnumWindowsCallback(HWND hwnd,LPARAM lParam)
{
int TitleLen;
char Title[512];
char ts[512];
// Say who we found
Title[0]='\0';
TitleLen=GetWindowText(hwn d,Title,51 1);
Title[511]='\0';
sprintf(ts," Window: <%s>",Title);
PutMSG(ts);
return true;
}
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
////////////////////////// ////////// ////////// ////////// ////////// ////////// / PutMSG
////////////////////////// ////////// ////////// ////////// ////////// ////////// ////////
void PutMSG(char * msg)
{
FILE * fh;
char tmpbuf[128];
struct _timeb tstruct;
_strtime(tmpbuf);
_ftime( &tstruct );
fh=fopen(LOGFile,"a");
fprintf(fh,"%s.%u - %s\n",tmpbuf,tstruct.milli tm,msg);
fclose(fh);
}
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winbase.h>
#include <winsvc.h>
#include <process.h>
#include <shellapi.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
BOOL CALLBACK EnumWindowStaCallback(LPTS
BOOL CALLBACK EnumDesktopCallback(LPTSTR
BOOL CALLBACK EnumWindowsCallback(HWND,L
void PutMSG(char*);
char MyFullName[512];
char LOGFile[512];
char EXEFile[512];
//////////////////////////
//////////////////////////
//////////////////////////
void main(int argc ,char * argv[])
{
int RC;
char ts[512];
// Get our full name
GetModuleFileName(NULL,MyF
sprintf(EXEFile,"%s",MyFul
// Put the log file in the same directory
MyFullName[strlen(MyFullNa
sprintf(LOGFile,"%s.log",M
RC=EnumWindowStations(Enum
return;
}
//////////////////////////
//////////////////////////
//////////////////////////
BOOL CALLBACK EnumWindowStaCallback(char
{
char ts[512];
HWINSTA hstation;
BOOL RC;
// Say who we found
PutMSG(" ");
sprintf(ts,"Station: <%s>",StationName);
PutMSG(ts);
// Enumerate this station's desktops
hstation=OpenWindowStation
|WINSTA_ACCESSGLOBALATOMS
|WINSTA_ENUMDESKTOPS
|WINSTA_ENUMERATE
|WINSTA_READATTRIBUTES
|WINSTA_READSCREEN);
if (hstation==NULL)
{
sprintf(ts,"OpenWindowStat
PutMSG(ts);
return true;
}
RC=EnumDesktops(hstation,E
if (!RC)
{
sprintf(ts,"EnumDesktops failure(%d)",GetLastError(
PutMSG(ts);
}
CloseWindowStation(hstatio
return true;
}
//////////////////////////
//////////////////////////
//////////////////////////
BOOL CALLBACK EnumDesktopCallback(LPTSTR
{
char ts[512];
HDESK hdesktop;
BOOL RC;
// Say who we found
sprintf(ts," Desktop: <%s>",DesktopName);
PutMSG(ts);
// Enumerate this desktop's windows
hdesktop=OpenDesktop(Deskt
if (hdesktop==NULL)
{
sprintf(ts," OpenDesktop failure(%d)",GetLastError(
PutMSG(ts);
return true;
}
RC=EnumDesktopWindows(hdes
if (!RC)
{
sprintf(ts," EnumWindows failure(%d)",GetLastError(
PutMSG(ts);
}
CloseDesktop(hdesktop);
return true;
}
//////////////////////////
//////////////////////////
//////////////////////////
BOOL CALLBACK EnumWindowsCallback(HWND hwnd,LPARAM lParam)
{
int TitleLen;
char Title[512];
char ts[512];
// Say who we found
Title[0]='\0';
TitleLen=GetWindowText(hwn
Title[511]='\0';
sprintf(ts," Window: <%s>",Title);
PutMSG(ts);
return true;
}
//////////////////////////
//////////////////////////
//////////////////////////
void PutMSG(char * msg)
{
FILE * fh;
char tmpbuf[128];
struct _timeb tstruct;
_strtime(tmpbuf);
_ftime( &tstruct );
fh=fopen(LOGFile,"a");
fprintf(fh,"%s.%u - %s\n",tmpbuf,tstruct.milli
fclose(fh);
}
ASKER
Wow that is a fast recovery time for a lost drive :O
the code is cool... it works n everything, but im getting
11:23:18.539 - Desktop: <Winlogon>
11:23:18.539 - OpenDesktop failure(5)
for the winlogon desktop. maybe it is because i was already logged on or something.
im *really* getting held up with excess assignments here, so i dont think i will be able to spend any time on this until the weekend.
when i do eventually get around to it, ill put your code into a service and see what's going on...
cheers,
southern curriez
the code is cool... it works n everything, but im getting
11:23:18.539 - Desktop: <Winlogon>
11:23:18.539 - OpenDesktop failure(5)
for the winlogon desktop. maybe it is because i was already logged on or something.
im *really* getting held up with excess assignments here, so i dont think i will be able to spend any time on this until the weekend.
when i do eventually get around to it, ill put your code into a service and see what's going on...
cheers,
southern curriez
>>Wow that is a fast recovery time for a lost drive :O
Actually, the drive crashed on Saturday and the restore and various installs today went faster than expected.
(sure am glad I daily incrementals)
Anyway, if the error 5 is accurate, that means it's a rights problem.
Actually, the drive crashed on Saturday and the restore and various installs today went faster than expected.
(sure am glad I daily incrementals)
Anyway, if the error 5 is accurate, that means it's a rights problem.
I just ran it and got a similar result.
I posted the code from an old archive of working code from a little over a year ago - when it worked. I haven't moved to XP SP2 yet, so I can only assume one of the many intermediate fixes, uh, 'fixed' something.
I'll look into it.
I posted the code from an old archive of working code from a little over a year ago - when it worked. I haven't moved to XP SP2 yet, so I can only assume one of the many intermediate fixes, uh, 'fixed' something.
I'll look into it.
I put in in a LocalSystem service, and it was happy with WinLogon:
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winbase.h>
#include <winsvc.h>
#include <process.h>
#include <shellapi.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <winreg.h>
VOID WINAPI SvcMain(DWORD,LPTSTR*);
VOID WINAPI SvcHandler(DWORD);
VOID Install(char*,char*);
BOOL CALLBACK EnumWindowStaCallback(LPTS TR,LPARAM) ;
BOOL CALLBACK EnumDesktopCallback(LPTSTR ,LPARAM);
BOOL CALLBACK EnumWindowsCallback(HWND,L PARAM);
void PutMSG(char*);
char MyFullName[512];
char LOGFile[512];
char EXEFile[512];
char SvcName[512];
// Service management
SERVICE_STATUS SvcStatusInfo;
SERVICE_STATUS_HANDLE SvcStatusHandle;
SERVICE_TABLE_ENTRY DispatchTable[]={{"EnumSvc ",SvcMain} ,{NULL, NULL}};
////////////////////////// ////////// ////////// ////////// ////////// //////////
////////////////////////// ////////// ////////// ////////// ////////// ////////// main
////////////////////////// ////////// ////////// ////////// ////////// ////////// /////
void main(int argc ,char * argv[])
{
strcpy(SvcName,"EnumSvc");
// Get our full name
GetModuleFileName(NULL,MyF ullName,51 1);
sprintf(EXEFile,"%s",MyFul lName);
// Put the log file in the same directory
MyFullName[strlen(MyFullNa me)-4]='\0 ';
sprintf(LOGFile,"%s.log",M yFullName) ;
// -i parm says to install and start the service
if (argc>1)
{
if (0==stricmp(argv[1],"-i"))
{
Install(EXEFile,SvcName);
return;
}
}
// We're not installing - this is the real thing
if (!StartServiceCtrlDispatch er(Dispatc hTable))
{
char ts[512];
sprintf(ts,"StartServiceCt rlDispatch er failure (%d)",GetLastError());
PutMSG(ts);
}
return;
}
////////////////////////// ////////// ////////// ////////// ////////// //////////
////////////////////////// ////////// ////////// ////////// ////////// ////////// Install
////////////////////////// ////////// ////////// ////////// ////////// ////////// ////////
VOID Install(char* ExePath, char* SvcName)
{
SC_HANDLE SCM,svc;
char ts[256];
PutMSG("Installing");
SCM=OpenSCManager(NULL,NUL L,SC_MANAG ER_CREATE_ SERVICE);
if (SCM==0)
{
sprintf(ts,"OpenSCManager failure (%d)",GetLastError());
PutMSG(ts);
}
else
{
svc=CreateService(SCM
,SvcName
,SvcName
,SERVICE_ALL_ACCESS
,SERVICE_WIN32_OWN_PROCESS |SERVICE_I NTERACTIVE _PROCESS
,SERVICE_AUTO_START
,SERVICE_ERROR_NORMAL
,ExePath
,NULL
,NULL
,NULL
,".\\LocalSystem"
,"");
if (svc==0)
{
sprintf(ts,"CreateService failure (%d)",GetLastError());
PutMSG(ts);
}
else
{
PutMSG("Install successful");
if (!StartService(svc,0,NULL) )
{
sprintf(ts,"StartService failure (%d)",GetLastError());
PutMSG(ts);
}
CloseServiceHandle(svc);
}
CloseServiceHandle(SCM);
}
}
////////////////////////// ////////// ////////// ////////// ////////// ////
////////////////////////// ////////// ////////// ////////// ////////// //// SvcMain
////////////////////////// ////////// ////////// ////////// ////////// ////////// //
VOID WINAPI SvcMain(DWORD SvcArgc,LPTSTR *SvcArgv )
{
int RC;
DWORD status=0;
char ts[512];
SvcStatusInfo.dwServiceTyp e =SERVICE_WIN32;
SvcStatusInfo.dwCurrentSta te =SERVICE_START_PENDING;
SvcStatusInfo.dwControlsAc cepted =SERVICE_ACCEPT_STOP
|SERVICE_ACCEPT_SHUTDOWN
|SERVICE_ACCEPT_PAUSE_CONT INUE;
SvcStatusInfo.dwWin32ExitC ode =0;
SvcStatusInfo.dwServiceSpe cificExitC ode =0;
SvcStatusInfo.dwCheckPoint =0;
SvcStatusInfo.dwWaitHint =0;
SvcStatusHandle=RegisterSe rviceCtrlH andler(Svc Name,SvcHa ndler);
if (SvcStatusHandle==0)
{
sprintf(ts,"RegisterServic eCtrlHandl er failure (%d)",GetLastError());
PutMSG(ts);
//@@@@@ shut down
return;
}
// oopsie?
status=GetLastError();
if (status!=NO_ERROR)
{
SvcStatusInfo.dwCurrentSta te =SERVICE_STOPPED;
SvcStatusInfo.dwCheckPoint =0;
SvcStatusInfo.dwWaitHint =0;
SvcStatusInfo.dwWin32ExitC ode =status;
SvcStatusInfo.dwServiceSpe cificExitC ode =0;
SetServiceStatus(SvcStatus Handle,&Sv cStatusInf o);
return;
}
// Initialization complete - report running status
SvcStatusInfo.dwCurrentSta te =SERVICE_RUNNING;
SvcStatusInfo.dwCheckPoint =0;
SvcStatusInfo.dwWaitHint =0;
if (!SetServiceStatus(SvcStat usHandle,& SvcStatusI nfo))
{
sprintf(ts,"SetServiceStat us failure(%d)",GetLastError( ));
PutMSG(ts);
//@@@@@ shut down
}
PutMSG("SvcMain Initialized");
while (true)
{
RC=EnumWindowStations(Enum WindowStaC allback,0) ;
sprintf(ts,"RC=%d LE=%d",RC,GetLastError());
Sleep(10000);
}
}
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
////////////////////////// ////////// ////////// ////////// ////////// ////////// / EnumWindowStaCallback
////////////////////////// ////////// ////////// ////////// ////////// ////////// ////////// ////////// ///
BOOL CALLBACK EnumWindowStaCallback(char * StationName,LPARAM lParam)
{
char ts[512];
HWINSTA hstation;
BOOL RC;
// Say who we found
PutMSG(" ");
sprintf(ts,"Station: %s",StationName);
PutMSG(ts);
// Enumerate this station's desktops
hstation=OpenWindowStation (StationNa me,true,ST ANDARD_RIG HTS_REQUIR ED
|WINSTA_ACCESSGLOBALATOMS
|WINSTA_ENUMDESKTOPS
|WINSTA_ENUMERATE
|WINSTA_READATTRIBUTES
|WINSTA_READSCREEN);
if (hstation==NULL)
{
sprintf(ts,"OpenWindowStat ion failure(%d)",GetLastError( ));
PutMSG(ts);
return true;
}
RC=EnumDesktops(hstation,E numDesktop Callback,l Param);
if (!RC)
{
sprintf(ts,"EnumDesktops failure(%d)",GetLastError( ));
PutMSG(ts);
}
CloseWindowStation(hstatio n);
return true;
}
////////////////////////// ////////// ////////// ////////// ////////// /
////////////////////////// ////////// ////////// ////////// ////////// / EnumDesktopCallback
////////////////////////// ////////// ////////// ////////// ////////// ////////// ////////// /
BOOL CALLBACK EnumDesktopCallback(LPTSTR DesktopName,LPARAM lParam)
{
char ts[512];
HDESK hdesktop;
BOOL RC;
// Say who we found
sprintf(ts," Desktop: %s",DesktopName);
PutMSG(ts);
// Enumerate this desktop's windows
hdesktop=OpenDesktop(Deskt opName,0,t rue,DESKTO P_ENUMERAT E|DESKTOP_ READOBJECT S|MAXIMUM_ ALLOWED);
if (hdesktop==NULL)
{
sprintf(ts," OpenDesktop failure(%d)",GetLastError( ));
PutMSG(ts);
return true;
}
RC=EnumDesktopWindows(hdes ktop,EnumW indowsCall back,lPara m);
if (!RC)
{
sprintf(ts," EnumWindows failure(%d)",GetLastError( ));
PutMSG(ts);
}
CloseDesktop(hdesktop);
return true;
}
////////////////////////// ////////// ////////// ////////// ////////// /
////////////////////////// ////////// ////////// ////////// ////////// / EnumWindowsCallback
////////////////////////// ////////// ////////// ////////// ////////// ////////// ////////// /
BOOL CALLBACK EnumWindowsCallback(HWND hwnd,LPARAM lParam)
{
int TitleLen;
char Title[512];
char ts[512];
// Say who we found
Title[0]='\0';
TitleLen=GetWindowText(hwn d,Title,51 1);
Title[511]='\0';
sprintf(ts," Window: %s",Title);
PutMSG(ts);
return true;
}
////////////////////////// ////////// ////////// ////////// ////////// /
////////////////////////// ////////// ////////// ////////// ////////// / SvcHandler
////////////////////////// ////////// ////////// ////////// ////////// ////////// //
VOID WINAPI SvcHandler(DWORD fdwControl)
{
char ts[256];
switch (fdwControl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
SvcStatusInfo.dwWin32ExitC ode = 0;
SvcStatusInfo.dwCurrentSta te = SERVICE_STOPPED;
SvcStatusInfo.dwCheckPoint = 0;
SvcStatusInfo.dwWaitHint = 0;
SetServiceStatus(SvcStatus Handle,&Sv cStatusInf o);
PutMSG("Stopped");
return;
case SERVICE_CONTROL_INTERROGAT E:
break;
default:
sprintf(ts,"Unhandled message (%d)",fdwControl);
PutMSG(ts);
break;
};
if (!SetServiceStatus(SvcStat usHandle, &SvcStatusInfo))
{
sprintf(ts,"SetServiceStat us failure (%d)",GetLastError());
PutMSG(ts);
}
}
////////////////////////// ////////// ////////// ////////// ////////// ////////// /
////////////////////////// ////////// ////////// ////////// ////////// ////////// / PutMSG
////////////////////////// ////////// ////////// ////////// ////////// ////////// ////////
void PutMSG(char * msg)
{
FILE * fh;
char tmpbuf[128];
struct _timeb tstruct;
_strtime(tmpbuf);
_ftime( &tstruct );
fh=fopen(LOGFile,"a");
fprintf(fh,"%s.%u - %s\n",tmpbuf,tstruct.milli tm,msg);
fclose(fh);
}
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <winbase.h>
#include <winsvc.h>
#include <process.h>
#include <shellapi.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <winreg.h>
VOID WINAPI SvcMain(DWORD,LPTSTR*);
VOID WINAPI SvcHandler(DWORD);
VOID Install(char*,char*);
BOOL CALLBACK EnumWindowStaCallback(LPTS
BOOL CALLBACK EnumDesktopCallback(LPTSTR
BOOL CALLBACK EnumWindowsCallback(HWND,L
void PutMSG(char*);
char MyFullName[512];
char LOGFile[512];
char EXEFile[512];
char SvcName[512];
// Service management
SERVICE_STATUS SvcStatusInfo;
SERVICE_STATUS_HANDLE SvcStatusHandle;
SERVICE_TABLE_ENTRY DispatchTable[]={{"EnumSvc
//////////////////////////
//////////////////////////
//////////////////////////
void main(int argc ,char * argv[])
{
strcpy(SvcName,"EnumSvc");
// Get our full name
GetModuleFileName(NULL,MyF
sprintf(EXEFile,"%s",MyFul
// Put the log file in the same directory
MyFullName[strlen(MyFullNa
sprintf(LOGFile,"%s.log",M
// -i parm says to install and start the service
if (argc>1)
{
if (0==stricmp(argv[1],"-i"))
{
Install(EXEFile,SvcName);
return;
}
}
// We're not installing - this is the real thing
if (!StartServiceCtrlDispatch
{
char ts[512];
sprintf(ts,"StartServiceCt
PutMSG(ts);
}
return;
}
//////////////////////////
//////////////////////////
//////////////////////////
VOID Install(char* ExePath, char* SvcName)
{
SC_HANDLE SCM,svc;
char ts[256];
PutMSG("Installing");
SCM=OpenSCManager(NULL,NUL
if (SCM==0)
{
sprintf(ts,"OpenSCManager failure (%d)",GetLastError());
PutMSG(ts);
}
else
{
svc=CreateService(SCM
,SvcName
,SvcName
,SERVICE_ALL_ACCESS
,SERVICE_WIN32_OWN_PROCESS
,SERVICE_AUTO_START
,SERVICE_ERROR_NORMAL
,ExePath
,NULL
,NULL
,NULL
,".\\LocalSystem"
,"");
if (svc==0)
{
sprintf(ts,"CreateService failure (%d)",GetLastError());
PutMSG(ts);
}
else
{
PutMSG("Install successful");
if (!StartService(svc,0,NULL)
{
sprintf(ts,"StartService failure (%d)",GetLastError());
PutMSG(ts);
}
CloseServiceHandle(svc);
}
CloseServiceHandle(SCM);
}
}
//////////////////////////
//////////////////////////
//////////////////////////
VOID WINAPI SvcMain(DWORD SvcArgc,LPTSTR *SvcArgv )
{
int RC;
DWORD status=0;
char ts[512];
SvcStatusInfo.dwServiceTyp
SvcStatusInfo.dwCurrentSta
SvcStatusInfo.dwControlsAc
|SERVICE_ACCEPT_SHUTDOWN
|SERVICE_ACCEPT_PAUSE_CONT
SvcStatusInfo.dwWin32ExitC
SvcStatusInfo.dwServiceSpe
SvcStatusInfo.dwCheckPoint
SvcStatusInfo.dwWaitHint =0;
SvcStatusHandle=RegisterSe
if (SvcStatusHandle==0)
{
sprintf(ts,"RegisterServic
PutMSG(ts);
//@@@@@ shut down
return;
}
// oopsie?
status=GetLastError();
if (status!=NO_ERROR)
{
SvcStatusInfo.dwCurrentSta
SvcStatusInfo.dwCheckPoint
SvcStatusInfo.dwWaitHint =0;
SvcStatusInfo.dwWin32ExitC
SvcStatusInfo.dwServiceSpe
SetServiceStatus(SvcStatus
return;
}
// Initialization complete - report running status
SvcStatusInfo.dwCurrentSta
SvcStatusInfo.dwCheckPoint
SvcStatusInfo.dwWaitHint =0;
if (!SetServiceStatus(SvcStat
{
sprintf(ts,"SetServiceStat
PutMSG(ts);
//@@@@@ shut down
}
PutMSG("SvcMain Initialized");
while (true)
{
RC=EnumWindowStations(Enum
sprintf(ts,"RC=%d LE=%d",RC,GetLastError());
Sleep(10000);
}
}
//////////////////////////
//////////////////////////
//////////////////////////
BOOL CALLBACK EnumWindowStaCallback(char
{
char ts[512];
HWINSTA hstation;
BOOL RC;
// Say who we found
PutMSG(" ");
sprintf(ts,"Station: %s",StationName);
PutMSG(ts);
// Enumerate this station's desktops
hstation=OpenWindowStation
|WINSTA_ACCESSGLOBALATOMS
|WINSTA_ENUMDESKTOPS
|WINSTA_ENUMERATE
|WINSTA_READATTRIBUTES
|WINSTA_READSCREEN);
if (hstation==NULL)
{
sprintf(ts,"OpenWindowStat
PutMSG(ts);
return true;
}
RC=EnumDesktops(hstation,E
if (!RC)
{
sprintf(ts,"EnumDesktops failure(%d)",GetLastError(
PutMSG(ts);
}
CloseWindowStation(hstatio
return true;
}
//////////////////////////
//////////////////////////
//////////////////////////
BOOL CALLBACK EnumDesktopCallback(LPTSTR
{
char ts[512];
HDESK hdesktop;
BOOL RC;
// Say who we found
sprintf(ts," Desktop: %s",DesktopName);
PutMSG(ts);
// Enumerate this desktop's windows
hdesktop=OpenDesktop(Deskt
if (hdesktop==NULL)
{
sprintf(ts," OpenDesktop failure(%d)",GetLastError(
PutMSG(ts);
return true;
}
RC=EnumDesktopWindows(hdes
if (!RC)
{
sprintf(ts," EnumWindows failure(%d)",GetLastError(
PutMSG(ts);
}
CloseDesktop(hdesktop);
return true;
}
//////////////////////////
//////////////////////////
//////////////////////////
BOOL CALLBACK EnumWindowsCallback(HWND hwnd,LPARAM lParam)
{
int TitleLen;
char Title[512];
char ts[512];
// Say who we found
Title[0]='\0';
TitleLen=GetWindowText(hwn
Title[511]='\0';
sprintf(ts," Window: %s",Title);
PutMSG(ts);
return true;
}
//////////////////////////
//////////////////////////
//////////////////////////
VOID WINAPI SvcHandler(DWORD fdwControl)
{
char ts[256];
switch (fdwControl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
SvcStatusInfo.dwWin32ExitC
SvcStatusInfo.dwCurrentSta
SvcStatusInfo.dwCheckPoint
SvcStatusInfo.dwWaitHint = 0;
SetServiceStatus(SvcStatus
PutMSG("Stopped");
return;
case SERVICE_CONTROL_INTERROGAT
break;
default:
sprintf(ts,"Unhandled message (%d)",fdwControl);
PutMSG(ts);
break;
};
if (!SetServiceStatus(SvcStat
{
sprintf(ts,"SetServiceStat
PutMSG(ts);
}
}
//////////////////////////
//////////////////////////
//////////////////////////
void PutMSG(char * msg)
{
FILE * fh;
char tmpbuf[128];
struct _timeb tstruct;
_strtime(tmpbuf);
_ftime( &tstruct );
fh=fopen(LOGFile,"a");
fprintf(fh,"%s.%u - %s\n",tmpbuf,tstruct.milli
fclose(fh);
}
ASKER
i finally managed to get on top of my workload, so my spare time is gradually increasing...
i tested out (my modified c++ code) in a service and everything (including GetWindowText) worked fine...
i wrote a new code which was basically
if(WINDOW_STATION == "WinSta0")
{
if(DESKTOP == "Winlogon")
{
launch_cmd();
}
}
void launch_cmd()
{
STARTUPINFO si ;
PROCESS_INFORMATION pi ;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof (STARTUPINFO);
si.wShowWindow = SW_SHOW;
si.lpDesktop = THE_HDESK_OF_WINLOGON;
CreateProcess (NULL, "cmd.exe" , NULL , NULL , FALSE , 0 , NULL , NULL, &si, &pi);
}
however it didnt work...
any ideaz why?
i tested out (my modified c++ code) in a service and everything (including GetWindowText) worked fine...
i wrote a new code which was basically
if(WINDOW_STATION == "WinSta0")
{
if(DESKTOP == "Winlogon")
{
launch_cmd();
}
}
void launch_cmd()
{
STARTUPINFO si ;
PROCESS_INFORMATION pi ;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof (STARTUPINFO);
si.wShowWindow = SW_SHOW;
si.lpDesktop = THE_HDESK_OF_WINLOGON;
CreateProcess (NULL, "cmd.exe" , NULL , NULL , FALSE , 0 , NULL , NULL, &si, &pi);
}
however it didnt work...
any ideaz why?
ASKER
* replace THE_HDESK_OF_WINLOGON with THE_STRING_NAME_OF_WINLOGO N
ASKER
i got it to work
thanks for the help :)
thanks for the help :)
Well, with all that spare time they can dump more work on you...
Help, I am using that code example above in a windows service in Vista and i am not seeing my windows. here is the output i get:
17:13:24.988 -
17:13:24.989 - Station: <WinSta0>
17:13:24.989 - Desktop: <Default>
17:13:24.989 - Window: <Wrapper Controlled JVM Console ID 114132523 (Do not close)>
17:13:24.990 - Window: <>
17:13:24.990 - Window: <>
17:13:24.990 - Window: <Default IME>
17:13:24.991 - Window: <Default IME>
17:13:24.991 - Desktop: <Disconnect>
17:13:24.991 - EnumWindows failure(183)
17:13:24.991 - Desktop: <Winlogon>
17:13:24.992 - EnumWindows failure(183)
17:13:24.992 -
17:13:24.992 - Station: <Service-0x0-3e7$>
17:13:24.993 - OpenWindowStation failure(5)
17:13:24.993 -
17:13:24.993 - Station: <Service-0x0-3e4$>
17:13:24.994 - OpenWindowStation failure(5)
17:13:24.994 -
17:13:24.994 - Station: <Service-0x0-3e5$>
17:13:24.995 - OpenWindowStation failure(5)
17:13:24.995 -
17:13:24.996 - Station: <msswindowstation>
17:13:24.996 - OpenWindowStation failure(5)
17:13:24.988 -
17:13:24.989 - Station: <WinSta0>
17:13:24.989 - Desktop: <Default>
17:13:24.989 - Window: <Wrapper Controlled JVM Console ID 114132523 (Do not close)>
17:13:24.990 - Window: <>
17:13:24.990 - Window: <>
17:13:24.990 - Window: <Default IME>
17:13:24.991 - Window: <Default IME>
17:13:24.991 - Desktop: <Disconnect>
17:13:24.991 - EnumWindows failure(183)
17:13:24.991 - Desktop: <Winlogon>
17:13:24.992 - EnumWindows failure(183)
17:13:24.992 -
17:13:24.992 - Station: <Service-0x0-3e7$>
17:13:24.993 - OpenWindowStation failure(5)
17:13:24.993 -
17:13:24.993 - Station: <Service-0x0-3e4$>
17:13:24.994 - OpenWindowStation failure(5)
17:13:24.994 -
17:13:24.994 - Station: <Service-0x0-3e5$>
17:13:24.995 - OpenWindowStation failure(5)
17:13:24.995 -
17:13:24.996 - Station: <msswindowstation>
17:13:24.996 - OpenWindowStation failure(5)
ASKER
take EnumWindowStatiosn() for example
it will return the names of every WindowStation to the callback function - how will i know which is the correct one?
i will need some exceptions like
IF(STATION_NAME == MAGIC_VALUE_1) //go ahead and call EnumDesktops
IF(DESKTOP_NAME == MAGIC_VALUE_2) //go ahead and call EnumDesktopWindows
IF(DESKTOP_WINDOW_NAME == MAGIC_VALUE_3) //go ahead and hook
but what can i use for these magic values?