summaryrefslogtreecommitdiff
path: root/protocols/SkypeClassic/src/alogon.cpp
blob: 6fc21d2cce8a044aa4ef3ba8f3b05e37eca16cf1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "skype.h"
#include "debug.h"

extern char g_szProtoName[];
extern HANDLE SkypeReady;

/**
 * Purpose: Retrieves class name from window
 *
 * Note: This is some sort of hack to return static local variable,
 * but it works :)
 */
static const TCHAR* getClassName(HWND wnd)
{
    static TCHAR className[256];
	
	*className=0;
	GetClassName(wnd, &className[0], sizeof(className)/sizeof(className[0]));
	return className;
}

/**
 * Purpose: Finds a window
 *
 * Note: This function relies on Skype window placement.
 * It should work for Skype 3.x
 */
static HWND findWindow(HWND parent, const TCHAR* childClassName)
{
    // Get child window
    // This window is not combo box or edit box
	HWND wnd = GetWindow(parent, GW_CHILD);
	while(wnd != NULL && _tcscmp(getClassName(wnd), childClassName) != 0)
		wnd = GetWindow(wnd, GW_HWNDNEXT);
    
    return wnd;
}

static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
	DWORD dwPID;
	GetWindowThreadProcessId(hWnd,&dwPID);
	if (lParam != 0 && dwPID != (DWORD)lParam) return TRUE;
	const TCHAR *lpszClassName = getClassName(hWnd);
	if(_tcscmp(lpszClassName, _T("tSkMainForm.UnicodeClass")) == 0 ||
		_tcscmp(lpszClassName, _T("TLoginForm.UnicodeClass")) == 0)
	{
		HWND loginControl = GetWindow(hWnd, GW_CHILD);

		LOG(("setUserNamePasswordThread: Skype window found!"));

		// Sleep for some time, while Skype is loading
		// It loads slowly :(
		//Sleep(5000);
		LOG (("TLoginControl = %S", getClassName(loginControl)));

		// Check for login control
		if(_tcscmp(getClassName(loginControl), _T("TLoginControl")) == 0)
		{
			// Find user name window
			HWND userName = findWindow(loginControl, _T("TNavigableTntComboBox.UnicodeClass"));
			HWND password = findWindow(loginControl, _T("TNavigableTntEdit.UnicodeClass"));

			LOG (("userName=%08X; password=%08X", userName, password));
			if (userName && password)
			{
				// Set user name and password
				DBVARIANT dbv;

				if(!db_get_ws(NULL,SKYPE_PROTONAME,"LoginUserName",&dbv)) 
				{
					SendMessageW(userName, WM_SETTEXT, 0, (LPARAM)dbv.pwszVal);
					db_free(&dbv);    
				}

				if(!db_get_ws(NULL,SKYPE_PROTONAME,"LoginPassword",&dbv)) 
				{
					SendMessageW(password, WM_SETTEXT, 0, (LPARAM)dbv.pwszVal);
					db_free(&dbv);
					SendMessageW(password, WM_CHAR, 13, 0);
				}


				SendMessageW(hWnd,
							 WM_COMMAND,
							 0x4a8,  // sign-in button; WARNING: This ID can change during newer Skype versions
							 (LPARAM)findWindow(loginControl, _T("TTntButton.UnicodeClass")));
			}
			return FALSE;
		}

	}
	return TRUE;
}

DWORD WINAPI setUserNamePasswordThread(LPVOID lpDummy)
{
	DWORD dwPid = (DWORD)lpDummy;
	HANDLE mutex = CreateMutex(NULL, TRUE, _T("setUserNamePasswordMutex"));

	// Check double entrance
	if(GetLastError() == ERROR_ALREADY_EXISTS)
		return 0;

	WaitForSingleObject(SkypeReady, 5000);
	EnumWindows(EnumWindowsProc, dwPid);

	ReleaseMutex(mutex);
	CloseHandle(mutex);
	return 0;
}

/**
 * Purpose: Finds Skype window and sets user name and password.
 *
 * Note: This function relies on Skype window placement.
 * It should work for Skype 3.x
 */
void setUserNamePassword(int dwPid)
{
	DWORD threadId;
	CreateThread(NULL, 0, &setUserNamePasswordThread, (LPVOID)dwPid, 0, &threadId);

	// Give time to thread
	Sleep(100);
}