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