Updated all files to GPL version 3.
[xboard.git] / winboard / wplugin.c
1 /*\r
2  * wplugin.c\r
3  *\r
4  * Copyright 2009 Free Software Foundation, Inc.\r
5  * ------------------------------------------------------------------------\r
6  *\r
7  * GNU XBoard is free software: you can redistribute it and/or modify\r
8  * it under the terms of the GNU General Public License as published by\r
9  * the Free Software Foundation, either version 3 of the License, or (at\r
10  * your option) any later version.\r
11  *\r
12  * GNU XBoard is distributed in the hope that it will be useful, but\r
13  * WITHOUT ANY WARRANTY; without even the implied warranty of\r
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
15  * General Public License for more details.\r
16  *\r
17  * You should have received a copy of the GNU General Public License\r
18  * along with this program. If not, see http://www.gnu.org/licenses/.  *\r
19  *\r
20  *------------------------------------------------------------------------\r
21  ** See the file ChangeLog for a revision history.  */\r
22 \r
23 #include "wplugin.h"\r
24 \r
25 static char * makePluginExeName( const char * name )\r
26 {\r
27     char buf[ MAX_PATH ];\r
28 \r
29     strcpy( buf, "" );\r
30 \r
31     strcat( buf, "plugins\\" );\r
32     strcat( buf, name );\r
33     strcat( buf, ".exe" );\r
34 \r
35     return strdup( buf );\r
36 }\r
37 \r
38 WbPlugin * wbpCreate( const char * name )\r
39 {\r
40     char buf[MAX_PATH];\r
41     int result = 0;\r
42 \r
43     // Create the plugin\r
44     WbPlugin * plugin = (WbPlugin *) malloc( sizeof(WbPlugin) );\r
45 \r
46     memset( plugin, 0, sizeof(WbPlugin) );\r
47 \r
48     plugin->name_ = strdup( name );\r
49     plugin->exe_name_ = makePluginExeName( name );\r
50     plugin->hPipe_ = INVALID_HANDLE_VALUE;\r
51     plugin->hProcess_ = INVALID_HANDLE_VALUE;\r
52 \r
53     // Create the named pipe for plugin communication\r
54     if( result == 0 ) {\r
55         strcpy( buf, "\\\\.\\pipe\\" );\r
56         strcat( buf, name );\r
57 \r
58         plugin->hPipe_ = CreateNamedPipe( buf,\r
59             PIPE_ACCESS_DUPLEX,\r
60             0, // Byte mode\r
61             2, // Max instances\r
62             4*1024,\r
63             4*1024,\r
64             1000, // Default timeout\r
65             NULL );\r
66 \r
67         if( plugin->hPipe_ == INVALID_HANDLE_VALUE ) {\r
68             DWORD err = GetLastError();\r
69             result = -1;\r
70         }\r
71     }\r
72 \r
73     // Create the plugin process\r
74     if( result == 0 ) {\r
75         STARTUPINFO si;\r
76         PROCESS_INFORMATION pi;\r
77 \r
78         ZeroMemory( &si, sizeof(si) );\r
79         ZeroMemory( &pi, sizeof(pi) );\r
80 \r
81         si.cb = sizeof(si);\r
82 \r
83         strcpy( buf, "\"" );\r
84         strcat( buf, plugin->exe_name_ );\r
85         strcat( buf, "\"" );\r
86 \r
87         strcpy( buf, "\"C:\\Program Files\\Borland\\Delphi5\\Projects\\History\\History.exe\"" );\r
88 \r
89         if( CreateProcess( NULL,\r
90             buf,\r
91             NULL,\r
92             NULL,\r
93             FALSE, // Inherit handles\r
94             0, // Creation flags\r
95             NULL, // Environment\r
96             NULL, // Current directory\r
97             &si,\r
98             &pi ) )\r
99         {\r
100             CloseHandle( pi.hThread );\r
101             plugin->hProcess_ = pi.hProcess;\r
102         }\r
103         else {\r
104             result = -2;\r
105         }\r
106     }\r
107 \r
108     // Destroy the plugin instance if something went wrong\r
109     if( result != 0 ) {\r
110         wbpDelete( plugin );\r
111         plugin = 0;\r
112     }\r
113 \r
114     return plugin;\r
115 }\r
116 \r
117 void wbpDelete( WbPlugin * plugin )\r
118 {\r
119     if( plugin != 0 ) {\r
120         if( plugin->hPipe_ != INVALID_HANDLE_VALUE ) {\r
121             CloseHandle( plugin->hPipe_ );\r
122         }\r
123 \r
124         if( plugin->hProcess_ != INVALID_HANDLE_VALUE ) {\r
125             CloseHandle( plugin->hProcess_ );\r
126         }\r
127 \r
128         free( plugin->name_ );\r
129 \r
130         free( plugin->exe_name_ );\r
131 \r
132         plugin->name_ = 0;\r
133         plugin->exe_name_ = 0;\r
134         plugin->hPipe_ = INVALID_HANDLE_VALUE;\r
135         plugin->hProcess_ = INVALID_HANDLE_VALUE;\r
136 \r
137         free( plugin );\r
138     }\r
139 }\r
140 \r
141 int wbpSendMessage( WbPlugin * plugin, const char * msg, size_t msg_len )\r
142 {\r
143     int result = -1;\r
144 \r
145     if( plugin != 0 && plugin->hPipe_ != INVALID_HANDLE_VALUE ) {\r
146         DWORD zf = 0;\r
147         BOOL ok = TRUE;\r
148 \r
149         while( ok && (msg_len > 0) ) {\r
150             DWORD cb = 0;\r
151 \r
152             ok = WriteFile( plugin->hPipe_,\r
153                 msg,\r
154                 msg_len,\r
155                 &cb,\r
156                 NULL );\r
157 \r
158             if( ok ) {\r
159                 if( cb > msg_len ) break; // Should *never* happen!\r
160 \r
161                 msg_len -= cb;\r
162                 msg += cb;\r
163             }\r
164 \r
165             if( cb == 0 ) {\r
166                 zf++;\r
167                 if( zf >= 3 ) ok = FALSE;\r
168             }\r
169             else {\r
170                 zf = 0;\r
171             }\r
172         }\r
173 \r
174         if( ok ) {\r
175             result = 0;\r
176         }\r
177     }\r
178 \r
179     return result;\r
180 }\r
181 \r
182 int wbpListInit( WbPluginList * list )\r
183 {\r
184     list->item_count_ = 0;\r
185 \r
186     return 0;\r
187 }\r
188 \r
189 int wbpListAdd( WbPluginList * list, WbPlugin * plugin )\r
190 {\r
191     int result = -1;\r
192 \r
193     if( plugin != 0 ) {\r
194         if( list->item_count_ < MaxWbPlugins ) {\r
195             list->item_[ list->item_count_ ] = plugin;\r
196             list->item_count_++;\r
197 \r
198             result = 0;\r
199         }\r
200     }\r
201 \r
202     return result;\r
203 }\r
204 \r
205 WbPlugin * wbpListGet( WbPluginList * list, int index )\r
206 {\r
207     WbPlugin * result = 0;\r
208 \r
209     if( index >= 0 && index < list->item_count_ ) {\r
210         result = list->item_[ index ];\r
211     }\r
212 \r
213     return result;\r
214 }\r
215 \r
216 int wbpListGetCount( WbPluginList * list )\r
217 {\r
218     return list->item_count_;\r
219 }\r
220 \r
221 int wbpListDeleteAll( WbPluginList * list )\r
222 {\r
223     int i;\r
224 \r
225     for( i=0; i<list->item_count_; i++ ) {\r
226         wbpDelete( list->item_[i] );\r
227     }\r
228 \r
229     return wbpListInit( list );\r
230 }\r
231 \r
232 int wbpListBroadcastMessage( WbPluginList * list, const char * msg, size_t msg_len )\r
233 {\r
234     int result = 0;\r
235     int i;\r
236 \r
237     for( i=0; i<list->item_count_; i++ ) {\r
238         if( wbpSendMessage( list->item_[i], msg, msg_len ) == 0 ) {\r
239             result++;\r
240         }\r
241         else {\r
242             // Error sending message to plugin...\r
243         }\r
244     }\r
245 \r
246     return result;\r
247 }\r