Statistics
| Revision:

root / trunk / base / ipc_win32.c @ 1919

History | View | Annotate | Download (7 KB)

1
/* 
2
    Copyright (C) 2005-2010  Erik van Pienbroek
3

                
4
    This program is free software; you can redistribute it and/or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation; either version 2 of the License, or
7
    (at your option) any later version.
8

                
9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
    GNU General Public License for more details.
13

                
14
    You should have received a copy of the GNU General Public License
15
    along with this program; if not, write to the Free Software
16
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
*/
18

                
19
#include 
20
#include 
21
#include "nntpgrab_utils.h"
22

                
23
HINSTANCE get_hinstance(void);
24

                
25
static HANDLE hMutex = NULL;
26
static NGOpenNZBCallback internal_open_nzb_callback = NULL;
27
static NGBringToFrontCallback internal_bring_to_front_callback = NULL;
28
static void *internal_user_data = NULL;
29

                
30
#define NNTPGRAB_WM_OPEN_NZB        WM_APP + 100
31
#define NNTPGRAB_WM_BRING_TO_FRONT  WM_APP + 101
32

                
33
ngboolean
34
nntpgrab_utils_test_is_frontend_already_running(ngboolean *is_running, char **errmsg)
35
{
36
    g_return_val_if_fail(is_running != NULL, FALSE);
37

                
38
    if (hMutex) {
39
        /* We managed to create a mutex for the name so we can assume there is no other NNTPGrab instance running */
40
        *is_running = FALSE;
41
        return TRUE;
42
    }
43

                
44
    if ((hMutex = CreateMutexA(NULL, FALSE, "nntpgrab_is_running"))) {
45
        DWORD err = GetLastError();
46
        if (err == ERROR_ALREADY_EXISTS) {
47
            *is_running = TRUE;
48
            return TRUE;
49
        } else if (err != ERROR_SUCCESS) {
50
            if (errmsg) {
51
                *errmsg = g_strdup_printf("Error (%u) accessing \"nntpgrab_is_running\" mutex.\n", (UINT) err);
52
            }
53
            return FALSE;
54
        }
55
    }
56

                
57
    *is_running = FALSE;
58
    return TRUE;
59
}
60

                
61
static LRESULT CALLBACK
62
wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
63
{
64
    g_return_val_if_fail(internal_open_nzb_callback != NULL, DefWindowProcA(hwnd, msg, wparam, lparam));
65

                
66
    if (msg == NNTPGRAB_WM_OPEN_NZB) {
67
        internal_open_nzb_callback((char *) lparam, internal_user_data);
68
        return TRUE;
69
    }
70

                
71
    return DefWindowProcA(hwnd, msg, wparam, lparam);
72
}
73

                
74
ngboolean
75
nntpgrab_utils_register_frontend(NGOpenNZBCallback open_nzb_callback, NGBringToFrontCallback bring_to_front_callback, void *user_data, char **errmsg)
76
{
77
    ngboolean is_running = FALSE;
78
    HWND win_hwnd;
79
    WNDCLASSEX wcx;
80
    LPCTSTR wname;
81

                
82
    g_return_val_if_fail(open_nzb_callback, FALSE);
83

                
84
    if (!nntpgrab_utils_test_is_frontend_already_running(&is_running, errmsg)) {
85
        return FALSE;
86
    }
87

                
88
    if (is_running) {
89
        if (errmsg) {
90
            *errmsg = g_strdup(_("An already running NNTPGrab frontend was detected"));
91
        }
92
        return FALSE;
93
    }
94

                
95
    wname = TEXT("NNTPGrabWinCls");
96

                
97
    wcx.cbSize = sizeof(wcx);
98
    wcx.style = 0;
99
    wcx.lpfnWndProc = wndproc;
100
    wcx.cbClsExtra = 0;
101
    wcx.cbWndExtra = 0;
102
    wcx.hInstance = /*get_hinstance()*/ NULL;           /* FIXME: get_hinstance() */
103
    wcx.hIcon = NULL;
104
    wcx.hCursor = NULL;
105
    wcx.hbrBackground = NULL;
106
    wcx.lpszMenuName = NULL;
107
    wcx.lpszClassName = wname;
108
    wcx.hIconSm = NULL;
109

                
110
    if (RegisterClassEx(&wcx) == 0) {
111
        char *last_error_msg = g_win32_error_message(GetLastError());
112
        *errmsg = g_strdup_printf("RegisterClassEx failed: %s (%u)", last_error_msg, (UINT) GetLastError());
113
        g_free(last_error_msg);
114

                
115
        return FALSE;
116
    }
117

                
118
    internal_open_nzb_callback = open_nzb_callback;
119
    internal_bring_to_front_callback = bring_to_front_callback;
120
    internal_user_data = user_data;
121

                
122
    /* Create the window */
123
    if(!(win_hwnd = CreateWindow(wname, TEXT("NNTPGrabWin"), 0, 0, 0, 0, 0, NULL, NULL, /*get_hinstance()*/ NULL, 0))) {        /* FIXME: get_hinstance() */
124
        char *last_error_msg = g_win32_error_message(GetLastError());
125
        *errmsg = g_strdup_printf("CreateWindow failed: %s (%u)", last_error_msg, (UINT) GetLastError());
126
        g_free(last_error_msg);
127

                
128
        return FALSE;
129
    }
130

                
131
    return TRUE;
132
}
133

                
134
void
135
nntpgrab_utils_unregister_frontend(void)
136
{
137
    if (hMutex) {
138
        ReleaseMutex(hMutex);
139
        hMutex = NULL;
140
    }
141
}
142

                
143
ngboolean
144
ipc_send_msg(UINT msg, const char *nzb_file, char **errmsg)
145
{
146
    char *remote_msg;
147
    HWND msg_win;
148
    DWORD pid;
149
    HANDLE process;
150
    SIZE_T len_written;
151
    ngboolean ret = TRUE;
152

                
153
    g_return_val_if_fail(nzb_file, FALSE);
154

                
155
    if (!(msg_win = FindWindowEx(NULL, NULL, TEXT("NNTPGrabWinCls"), NULL))) {
156
        if (errmsg) {
157
            *errmsg = g_strdup("Unable to find an instance of NNTPGrab to handle protocol message");
158
        }
159

                
160
        return FALSE;
161
    }
162

                
163
    GetWindowThreadProcessId(msg_win, &pid);
164
    if (!(process = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid))) {
165
        if (errmsg) {
166
            char *last_error_msg = g_win32_error_message(GetLastError());
167
            *errmsg = g_strdup_printf("Unable to open NNTPGrab process: %s (%u)", last_error_msg, (UINT) GetLastError());
168
            g_free(last_error_msg);
169
        }
170

                
171
        return FALSE;
172
    }
173

                
174
    /* MEM_COMMIT initializes the memory to zero, 
175
     * so we don't need to worry that our section of tmp1 isn't nul-terminated */
176
    if ((remote_msg = (char*) VirtualAllocEx(process, NULL, strlen(nzb_file) + 1, MEM_COMMIT, PAGE_READWRITE))) {
177
        if (WriteProcessMemory(process, remote_msg, nzb_file, strlen(nzb_file), &len_written)) {
178
            if (!SendMessageA(msg_win, msg, len_written, (LPARAM) remote_msg)) {
179
                if (errmsg) {
180
                    char *last_error_msg = g_win32_error_message(GetLastError());
181
                    *errmsg = g_strdup_printf("Unable to send protocol message to NNTPGrab instance: %s (%u)", last_error_msg, (UINT) GetLastError());
182
                    g_free(last_error_msg);
183
                }
184

                
185
                ret = FALSE;
186
            }
187
        } else {
188
            if (errmsg) {
189
                char *last_error_msg = g_win32_error_message(GetLastError());
190
                *errmsg = g_strdup_printf("Unable to write to remote memory: %s (%u)", last_error_msg, (UINT) GetLastError());
191
                g_free(last_error_msg);
192
            }
193

                
194
            ret = FALSE;
195
        }
196

                
197
        VirtualFreeEx(process, remote_msg, 0, MEM_RELEASE);
198
    } else {
199
        if (errmsg) {
200
            char *last_error_msg = g_win32_error_message(GetLastError());
201
            *errmsg = g_strdup_printf("Unable to allocate remote memory: %s (%u)", last_error_msg, (UINT) GetLastError());
202
        }
203

                
204
        ret = FALSE;
205
    }
206

                
207
    CloseHandle(process);
208

                
209
    return ret;
210
}
211

                
212
ngboolean
213
nntpgrab_utils_send_open_nzb_file_request(const char *nzb_file, char **errmsg)
214
{
215
    return ipc_send_msg(NNTPGRAB_WM_OPEN_NZB, nzb_file, errmsg);
216
}
217

                
218
ngboolean
219
nntpgrab_utils_send_bring_to_front_request(char **errmsg)
220
{
221
    return ipc_send_msg(NNTPGRAB_WM_BRING_TO_FRONT, "", errmsg);
222
}