/* * Skype cmd.exe plugin v0.1 - "listening master" module (c) 2006 Kostya Kortchinsky - EADS/DCR/STI/C * Compile with "cl /W3 plugin_master.c /MT" */ #include #include #include #pragma comment(lib, "rpcrt4.lib") #pragma comment(lib, "user32.lib") HWND hInit_MainWindowHandle; HINSTANCE hInit_ProcessHandle; char acInit_WindowClassName[128]; HANDLE hGlobal_ThreadShutdownEvent; BOOL volatile fGlobal_ThreadRunning = TRUE; UINT uiGlobal_MsgID_SkypeControlAPIAttach; UINT uiGlobal_MsgID_SkypeControlAPIDiscover; HWND hGlobal_SkypeAPIWindowHandle = NULL; DWORD ulGlobal_PromptConsoleMode = 0; HANDLE volatile hGlobal_PromptConsoleHandle = NULL; enum { SKYPECONTROLAPI_ATTACH_SUCCESS = 0, SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION = 1, SKYPECONTROLAPI_ATTACH_REFUSED = 2, SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE = 3, SKYPECONTROLAPI_ATTACH_API_AVAILABLE = 0x8001 }; char szMessageCreate[] = "CREATE APPLICATION minishell"; char szMessageStreams[] = "APPLICATION minishell STREAMS "; char szMessageDelete[] = "DELETE APPLICATION minishell"; char szMessageWrite[] = "ALTER APPLICATION minishell WRITE "; char szMessageSending[] = "APPLICATION minishell SENDING "; char szMessageReceived[] = "APPLICATION minishell RECEIVED "; char szMessageRead[] = "ALTER APPLICATION minishell READ "; static BYTE szStream[64]; void ProcessMessage(PCOPYDATASTRUCT poCopyData) { COPYDATASTRUCT oCopyData; static BYTE szBuffer[1152]; oCopyData.dwData = 0; oCopyData.lpData = NULL; memset(szBuffer, 0, sizeof(szBuffer)); if (stricmp(poCopyData->lpData, szMessageCreate) == 0) { OutputDebugString("[DEBUG] Application registration successful.\n"); } else if (strnicmp(poCopyData->lpData, szMessageStreams, strlen(szMessageStreams)) == 0) { memset(szStream, 0, sizeof(szStream)); strncpy(szStream, &(((char *)(poCopyData->lpData))[strlen(szMessageStreams)]), sizeof(szStream) - 1); if (strlen(szStream) == 0) OutputDebugString("[DEBUG] Stream closed.\n"); else OutputDebugString(szStream); } else if (stricmp(poCopyData->lpData, szMessageSending) == 0) { OutputDebugString("[DEBUG] Message successfully sent.\n"); } else if (strnicmp(poCopyData->lpData, szMessageReceived, strlen(szMessageReceived)) == 0) { if (strnicmp(szStream, &(((char *)(poCopyData->lpData))[strlen(szMessageReceived)]), strlen(szStream)) == 0) { OutputDebugString("[DEBUG] Incoming message.\n"); _snprintf(szBuffer, sizeof(szBuffer) - 1, "%s%s", szMessageRead, szStream); oCopyData.lpData = szBuffer; } } else if (strnicmp(poCopyData->lpData, szMessageRead, strlen(szMessageRead)) == 0) { if (strnicmp(szStream, &(((char *)(poCopyData->lpData))[strlen(szMessageRead)]), strlen(szStream)) == 0) { OutputDebugString("[DEBUG] Message received.\n"); strncpy(szBuffer, &(((char *)(poCopyData->lpData))[strlen(szMessageRead) + strlen(szStream) + 1]), sizeof(szBuffer) - 1); printf("%s", szBuffer); } } if (oCopyData.lpData != NULL) { oCopyData.cbData = strlen(oCopyData.lpData) + 1; if (SendMessage(hGlobal_SkypeAPIWindowHandle, WM_COPYDATA, (WPARAM)hInit_MainWindowHandle, (LPARAM)&oCopyData) == FALSE) hGlobal_SkypeAPIWindowHandle = NULL; } // printf( "Message from Skype(%u): %.*s\n", poCopyData->dwData, poCopyData->cbData, poCopyData->lpData); } BOOL Global_Console_ReadRow(char *pacPromptBuffer, unsigned int uiMaxLength) { HANDLE hConsoleHandle, hDuplicatedConsoleHandle; DWORD ulCharactersRead, ulConsoleMode; unsigned int uiNewLength; BOOL fReadConsoleResult; BOOL fReturnStatus; char cCharacter; fReturnStatus = FALSE; while ((hConsoleHandle = GetStdHandle(STD_INPUT_HANDLE)) != INVALID_HANDLE_VALUE) { if (DuplicateHandle(GetCurrentProcess(), hConsoleHandle, GetCurrentProcess(), &hDuplicatedConsoleHandle, 0, FALSE, DUPLICATE_SAME_ACCESS) == FALSE) break; GetConsoleMode(hDuplicatedConsoleHandle, &ulConsoleMode); SetConsoleMode(hDuplicatedConsoleHandle, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT); hGlobal_PromptConsoleHandle = hDuplicatedConsoleHandle; ulGlobal_PromptConsoleMode = ulConsoleMode; fReadConsoleResult = ReadConsole(hGlobal_PromptConsoleHandle, (LPVOID)pacPromptBuffer, uiMaxLength, &ulCharactersRead, (LPVOID)0); if (hGlobal_PromptConsoleHandle == (HANDLE)0) break; hGlobal_PromptConsoleHandle = (HANDLE)0; SetConsoleMode(hDuplicatedConsoleHandle, ulConsoleMode); CloseHandle(hDuplicatedConsoleHandle); if (fReadConsoleResult == FALSE || ulCharactersRead > uiMaxLength) break; pacPromptBuffer[ulCharactersRead] = 0; uiNewLength = ulCharactersRead; while (uiNewLength != 0) { cCharacter = pacPromptBuffer[uiNewLength - 1]; if (cCharacter != '\r' && cCharacter != '\n') break; uiNewLength--; } pacPromptBuffer[uiNewLength] = 0; fReturnStatus = TRUE; break; } if (fReturnStatus == FALSE) pacPromptBuffer[0] = 0; return(fReturnStatus); } void Global_Console_CancelReadRow(void) { if (hGlobal_PromptConsoleHandle != (HANDLE)0) { SetConsoleMode(hGlobal_PromptConsoleHandle, ulGlobal_PromptConsoleMode); CloseHandle(hGlobal_PromptConsoleHandle); hGlobal_PromptConsoleHandle = (HANDLE)0; } } static LRESULT APIENTRY SkypeAPITest_Windows_WindowProc(HWND hWindow, UINT uiMessage, WPARAM uiParam, LPARAM ulParam) { LRESULT lReturnCode; BOOL fIssueDefProc; COPYDATASTRUCT oCopyData; lReturnCode = 0; fIssueDefProc = FALSE; oCopyData.dwData = 0; switch(uiMessage) { case WM_DESTROY: hInit_MainWindowHandle = NULL; PostQuitMessage(0); break; case WM_COPYDATA: if (hGlobal_SkypeAPIWindowHandle == (HWND)uiParam) { ProcessMessage((PCOPYDATASTRUCT)ulParam); lReturnCode = 1; } break; default: if(uiMessage == uiGlobal_MsgID_SkypeControlAPIAttach) { switch(ulParam) { case SKYPECONTROLAPI_ATTACH_SUCCESS: hGlobal_SkypeAPIWindowHandle = (HWND)uiParam; oCopyData.lpData = szMessageCreate; oCopyData.cbData = strlen(oCopyData.lpData) + 1; if (SendMessage(hGlobal_SkypeAPIWindowHandle, WM_COPYDATA, (WPARAM)hInit_MainWindowHandle, (LPARAM)&oCopyData) == FALSE) hGlobal_SkypeAPIWindowHandle = NULL; break; case SKYPECONTROLAPI_ATTACH_PENDING_AUTHORIZATION: case SKYPECONTROLAPI_ATTACH_REFUSED: case SKYPECONTROLAPI_ATTACH_NOT_AVAILABLE: case SKYPECONTROLAPI_ATTACH_API_AVAILABLE: break; } lReturnCode = 1; break; } fIssueDefProc = TRUE; break; } if (fIssueDefProc) lReturnCode = DefWindowProc(hWindow, uiMessage, uiParam, ulParam); return (lReturnCode); } BOOL Initialize_CreateWindowClass(void) { unsigned char *paucUUIDString; RPC_STATUS lUUIDResult; BOOL fReturnStatus; UUID oUUID; fReturnStatus = FALSE; lUUIDResult = UuidCreate(&oUUID); hInit_ProcessHandle = (HINSTANCE)OpenProcess(PROCESS_DUP_HANDLE, FALSE, GetCurrentProcessId()); if (hInit_ProcessHandle != NULL && (lUUIDResult == RPC_S_OK || lUUIDResult == RPC_S_UUID_LOCAL_ONLY)) { if(UuidToString(&oUUID, &paucUUIDString) == RPC_S_OK) { WNDCLASS oWindowClass; strcpy(acInit_WindowClassName, "Skype-API-Test-"); strcat(acInit_WindowClassName, (char *)paucUUIDString); oWindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; oWindowClass.lpfnWndProc = (WNDPROC)&SkypeAPITest_Windows_WindowProc; oWindowClass.cbClsExtra = 0; oWindowClass.cbWndExtra = 0; oWindowClass.hInstance = hInit_ProcessHandle; oWindowClass.hIcon = NULL; oWindowClass.hCursor = NULL; oWindowClass.hbrBackground = NULL; oWindowClass.lpszMenuName = NULL; oWindowClass.lpszClassName = acInit_WindowClassName; if (RegisterClass(&oWindowClass) != 0) fReturnStatus = TRUE; RpcStringFree(&paucUUIDString); } } if (fReturnStatus == FALSE) CloseHandle(hInit_ProcessHandle), hInit_ProcessHandle = NULL; return (fReturnStatus); } void DeInitialize_DestroyWindowClass(void) { UnregisterClass(acInit_WindowClassName, hInit_ProcessHandle); CloseHandle(hInit_ProcessHandle), hInit_ProcessHandle = NULL; } BOOL Initialize_CreateMainWindow(void) { hInit_MainWindowHandle = CreateWindowEx(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, acInit_WindowClassName, "", WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 128, 128, NULL, 0, hInit_ProcessHandle, 0); return (hInit_MainWindowHandle != NULL ? TRUE : FALSE); } void DeInitialize_DestroyMainWindow(void) { if (hInit_MainWindowHandle != NULL) DestroyWindow(hInit_MainWindowHandle), hInit_MainWindowHandle = NULL; } void Global_MessageLoop(void) { MSG oMessage; while (GetMessage(&oMessage, 0, 0, 0) != FALSE) { TranslateMessage(&oMessage); DispatchMessage(&oMessage); } } void __cdecl Global_InputProcessingThread(void *pUnused) { static char acInputRow[1024]; static char szAP2APMessage[1024 + 128]; COPYDATASTRUCT oCopyData; oCopyData.dwData = 0; if (SendMessage(HWND_BROADCAST, uiGlobal_MsgID_SkypeControlAPIDiscover, (WPARAM)hInit_MainWindowHandle, 0) != 0) { while (Global_Console_ReadRow(acInputRow, sizeof(acInputRow) - 1)) { if (strlen(szStream) == 0) continue; _snprintf(szAP2APMessage, sizeof(szAP2APMessage) - 1, "%s%s %s", szMessageWrite, szStream, acInputRow); oCopyData.lpData = szAP2APMessage; oCopyData.cbData = strlen(oCopyData.lpData) + 1; if (oCopyData.cbData != 1) { if (SendMessage(hGlobal_SkypeAPIWindowHandle, WM_COPYDATA, (WPARAM)hInit_MainWindowHandle, (LPARAM)&oCopyData) == FALSE) { hGlobal_SkypeAPIWindowHandle = NULL; } } } } PostMessage(hInit_MainWindowHandle, WM_CLOSE, 0, 0); SetEvent(hGlobal_ThreadShutdownEvent); fGlobal_ThreadRunning = FALSE; } int main(int argc, char *argv[]) { memset(szStream, 0, sizeof(szStream)); uiGlobal_MsgID_SkypeControlAPIAttach = RegisterWindowMessage("SkypeControlAPIAttach"); uiGlobal_MsgID_SkypeControlAPIDiscover = RegisterWindowMessage("SkypeControlAPIDiscover"); if (uiGlobal_MsgID_SkypeControlAPIAttach != 0 && uiGlobal_MsgID_SkypeControlAPIDiscover != 0) { if (Initialize_CreateWindowClass()) { if (Initialize_CreateMainWindow()) { hGlobal_ThreadShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (hGlobal_ThreadShutdownEvent != NULL) { if (_beginthread(Global_InputProcessingThread, 64 * 1024, NULL) != (unsigned long)-1) { Global_MessageLoop(); Global_Console_CancelReadRow(); WaitForSingleObject(hGlobal_ThreadShutdownEvent, INFINITE); } CloseHandle(hGlobal_ThreadShutdownEvent); } DeInitialize_DestroyMainWindow(); } DeInitialize_DestroyWindowClass(); } } return 0; }