c6507d373129b4a203c78dc2a2f2035161c83bf0
[xboard.git] / winboard / wplugin.c
1 #include "wplugin.h"\r
2 \r
3 static char * makePluginExeName( const char * name )\r
4 {\r
5     char buf[ MAX_PATH ];\r
6 \r
7     strcpy( buf, "" );\r
8 \r
9     strcat( buf, "plugins\\" );\r
10     strcat( buf, name );\r
11     strcat( buf, ".exe" );\r
12 \r
13     return strdup( buf );\r
14 }\r
15 \r
16 WbPlugin * wbpCreate( const char * name )\r
17 {\r
18     char buf[MAX_PATH];\r
19     int result = 0;\r
20 \r
21     // Create the plugin\r
22     WbPlugin * plugin = (WbPlugin *) malloc( sizeof(WbPlugin) );\r
23 \r
24     memset( plugin, 0, sizeof(WbPlugin) );\r
25 \r
26     plugin->name_ = strdup( name );\r
27     plugin->exe_name_ = makePluginExeName( name );\r
28     plugin->hPipe_ = INVALID_HANDLE_VALUE;\r
29     plugin->hProcess_ = INVALID_HANDLE_VALUE;\r
30 \r
31     // Create the named pipe for plugin communication\r
32     if( result == 0 ) {\r
33         strcpy( buf, "\\\\.\\pipe\\" );\r
34         strcat( buf, name );\r
35 \r
36         plugin->hPipe_ = CreateNamedPipe( buf,\r
37             PIPE_ACCESS_DUPLEX,\r
38             0, // Byte mode\r
39             2, // Max instances\r
40             4*1024,\r
41             4*1024,\r
42             1000, // Default timeout\r
43             NULL );\r
44 \r
45         if( plugin->hPipe_ == INVALID_HANDLE_VALUE ) {\r
46             DWORD err = GetLastError();\r
47             result = -1;\r
48         }\r
49     }\r
50 \r
51     // Create the plugin process\r
52     if( result == 0 ) {\r
53         STARTUPINFO si;\r
54         PROCESS_INFORMATION pi;\r
55 \r
56         ZeroMemory( &si, sizeof(si) );\r
57         ZeroMemory( &pi, sizeof(pi) );\r
58 \r
59         si.cb = sizeof(si);\r
60 \r
61         strcpy( buf, "\"" );\r
62         strcat( buf, plugin->exe_name_ );\r
63         strcat( buf, "\"" );\r
64 \r
65         strcpy( buf, "\"C:\\Program Files\\Borland\\Delphi5\\Projects\\History\\History.exe\"" );\r
66 \r
67         if( CreateProcess( NULL,\r
68             buf,\r
69             NULL,\r
70             NULL,\r
71             FALSE, // Inherit handles\r
72             0, // Creation flags\r
73             NULL, // Environment\r
74             NULL, // Current directory\r
75             &si,\r
76             &pi ) )\r
77         {\r
78             CloseHandle( pi.hThread );\r
79             plugin->hProcess_ = pi.hProcess;\r
80         }\r
81         else {\r
82             result = -2;\r
83         }\r
84     }\r
85 \r
86     // Destroy the plugin instance if something went wrong\r
87     if( result != 0 ) {\r
88         wbpDelete( plugin );\r
89         plugin = 0;\r
90     }\r
91 \r
92     return plugin;\r
93 }\r
94 \r
95 void wbpDelete( WbPlugin * plugin )\r
96 {\r
97     if( plugin != 0 ) {\r
98         if( plugin->hPipe_ != INVALID_HANDLE_VALUE ) {\r
99             CloseHandle( plugin->hPipe_ );\r
100         }\r
101 \r
102         if( plugin->hProcess_ != INVALID_HANDLE_VALUE ) {\r
103             CloseHandle( plugin->hProcess_ );\r
104         }\r
105 \r
106         free( plugin->name_ );\r
107 \r
108         free( plugin->exe_name_ );\r
109 \r
110         plugin->name_ = 0;\r
111         plugin->exe_name_ = 0;\r
112         plugin->hPipe_ = INVALID_HANDLE_VALUE;\r
113         plugin->hProcess_ = INVALID_HANDLE_VALUE;\r
114 \r
115         free( plugin );\r
116     }\r
117 }\r
118 \r
119 int wbpSendMessage( WbPlugin * plugin, const char * msg, size_t msg_len )\r
120 {\r
121     int result = -1;\r
122 \r
123     if( plugin != 0 && plugin->hPipe_ != INVALID_HANDLE_VALUE ) {\r
124         DWORD zf = 0;\r
125         BOOL ok = TRUE;\r
126 \r
127         while( ok && (msg_len > 0) ) {\r
128             DWORD cb = 0;\r
129 \r
130             ok = WriteFile( plugin->hPipe_,\r
131                 msg,\r
132                 msg_len,\r
133                 &cb,\r
134                 NULL );\r
135 \r
136             if( ok ) {\r
137                 if( cb > msg_len ) break; // Should *never* happen!\r
138 \r
139                 msg_len -= cb;\r
140                 msg += cb;\r
141             }\r
142 \r
143             if( cb == 0 ) {\r
144                 zf++;\r
145                 if( zf >= 3 ) ok = FALSE;\r
146             }\r
147             else {\r
148                 zf = 0;\r
149             }\r
150         }\r
151 \r
152         if( ok ) {\r
153             result = 0;\r
154         }\r
155     }\r
156 \r
157     return result;\r
158 }\r
159 \r
160 int wbpListInit( WbPluginList * list )\r
161 {\r
162     list->item_count_ = 0;\r
163 \r
164     return 0;\r
165 }\r
166 \r
167 int wbpListAdd( WbPluginList * list, WbPlugin * plugin )\r
168 {\r
169     int result = -1;\r
170 \r
171     if( plugin != 0 ) {\r
172         if( list->item_count_ < MaxWbPlugins ) {\r
173             list->item_[ list->item_count_ ] = plugin;\r
174             list->item_count_++;\r
175 \r
176             result = 0;\r
177         }\r
178     }\r
179 \r
180     return result;\r
181 }\r
182 \r
183 WbPlugin * wbpListGet( WbPluginList * list, int index )\r
184 {\r
185     WbPlugin * result = 0;\r
186 \r
187     if( index >= 0 && index < list->item_count_ ) {\r
188         result = list->item_[ index ];\r
189     }\r
190 \r
191     return result;\r
192 }\r
193 \r
194 int wbpListGetCount( WbPluginList * list )\r
195 {\r
196     return list->item_count_;\r
197 }\r
198 \r
199 int wbpListDeleteAll( WbPluginList * list )\r
200 {\r
201     int i;\r
202 \r
203     for( i=0; i<list->item_count_; i++ ) {\r
204         wbpDelete( list->item_[i] );\r
205     }\r
206 \r
207     return wbpListInit( list );\r
208 }\r
209 \r
210 int wbpListBroadcastMessage( WbPluginList * list, const char * msg, size_t msg_len )\r
211 {\r
212     int result = 0;\r
213     int i;\r
214 \r
215     for( i=0; i<list->item_count_; i++ ) {\r
216         if( wbpSendMessage( list->item_[i], msg, msg_len ) == 0 ) {\r
217             result++;\r
218         }\r
219         else {\r
220             // Error sending message to plugin...\r
221         }\r
222     }\r
223 \r
224     return result;\r
225 }\r