http://prdownloads.sourceforge.net/lufs/lufs-0.9.7.tar.gz?download
[lufs.git] / filesystems / cefs / rapi.c
1 /***************************************************************************
2  *   Copyright (C) 2001 by Ludovic LANGE                                   *
3  *   ludovic.lange@free.fr                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  ***************************************************************************/
10 /*
11  * rapi.c
12  * (c) 2001 Ludovic LANGE,
13  * except SockOpen, (c) Unknown ? from socket.c / socket.h
14  */
15
16 #include "config.h"
17
18 #undef VERSION
19
20 #define MIN(a,b) ((a)<(b)?(a):(b))
21
22 #include <sys/time.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
30 #include <netdb.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <ctype.h>
35 #include <string.h>
36 #include <errno.h>
37
38 #include "little_endian.h"
39
40 #include "chunk.h"
41 #include "rapi.h"
42
43 #define BUFSIZE 16384
44
45
46 /*
47  * Push parameter information to the buffer
48  *
49  * DWORD parameter values must be 4 byte little-endian
50  * WORD parameter values must be 2 byte little-endian
51  * WCHAR parameter values must be 2-byte UNICODE (is it endian stuff on these too?) 
52  */
53 static void pushParameter(RAPIHandleP rhnd,long size, void * parameterData, size_t parameterSize, int pushValue)
54 {
55         if (parameterData)
56         {
57                 pushLong( (rhnd->buffer), size, 1 );
58                 pushLong( (rhnd->buffer), size, parameterSize);
59
60                 if (pushValue)  /* pushValue is boolean */
61                 {
62                         long old_length;
63                         long new_length;
64
65                         pushLong( (rhnd->buffer), size, 1 );    /* data follows */
66
67                         old_length = _getbufferlen((rhnd->buffer));
68                         new_length = old_length + parameterSize;
69
70                         if (new_length < size)
71                         {
72                                 memcpy(((unsigned char*)&((rhnd->buffer)->data)) + old_length, parameterData, parameterSize);
73                                 _setbufferlen((rhnd->buffer), new_length);
74                         }
75                         else
76                         {
77                                 DBG_printf( "rapibuffer too small, this will fail\n");
78                         }
79                 }
80                 else
81                 {
82                         pushLong( (rhnd->buffer), size, 0 );    /* no data follows */
83                 }
84         }
85         else
86         {
87                 pushLong( (rhnd->buffer), size, 0 ); /* no parameter info */
88         }
89 }
90
91 /*
92  * Push parameter information to the buffer, omitting size information (needed for CeRecordWriteProps
93  */
94 static void pushParameter_no_size(RAPIHandleP rhnd,long size, void * parameterData, size_t parameterSize)
95 {
96         long old_length;
97         long new_length;
98
99         if (parameterData)
100         {
101                 pushLong( (rhnd->buffer), size, 1 );    /* data follows */
102         
103                 old_length = _getbufferlen((rhnd->buffer));
104                 new_length = old_length + parameterSize;
105         
106                 if (new_length < size)
107                 {
108                         memcpy(((unsigned char*)&((rhnd->buffer)->data)) + old_length, parameterData, parameterSize);
109                         _setbufferlen((rhnd->buffer), new_length);
110                 }
111                 else
112                 {
113                         DBG_printf( "rapibuffer too small, this will fail\n");
114                 }
115         }
116         else
117         {
118                 pushLong( (rhnd->buffer), size, 0 );    /* no data follows */
119         }       
120 }
121
122
123
124
125 /**
126  * Convert parameter to little endian before call to pushParameter
127  */
128 #define pushParameterInt16(rhnd,size, parameterData, pushValue) \
129 if (pushValue && parameterData) \
130         { *(u_int16_t*)parameterData = htole16(*(u_int16_t*)parameterData); } \
131 pushParameter(rhnd,size, parameterData, sizeof(u_int16_t), pushValue);
132
133 #define pushParameterInt32(rhnd,size, parameterData, pushValue) \
134 if (pushValue && parameterData) \
135         { *(u_int32_t*)parameterData = htole32(*(u_int32_t*)parameterData); } \
136 pushParameter(rhnd,size, parameterData, sizeof(u_int32_t), pushValue)
137
138
139 /**
140  * Pop parameter info from the buffer
141  */
142 static void popParameter(RAPIHandleP rhnd,long* size, void * parameterData, size_t parameterMaxSize)
143 {
144         long lng;
145         
146         lng = getLong((rhnd->sock), size);      /* parameter info available? */
147
148         if (1 == lng)
149         {
150                 size_t parameterRealSize = getLong((rhnd->sock), size); /* parameter value size in buffer */
151
152                 lng = getLong((rhnd->sock), size); /* parameter value available? */
153
154                 if (1 == lng)
155                 {
156                         int overflow; 
157
158                         if (parameterData)
159                         {
160                                 /* read directly to buffer */
161                                 getbufferchunk((rhnd->sock), size, parameterData, MIN(parameterRealSize, parameterMaxSize));
162                                 overflow = parameterRealSize - parameterMaxSize;
163                         }
164                         else
165                         {
166                                 /* throw it all away */
167                                 overflow = parameterRealSize;
168                         }
169                                 
170                         if (overflow > 0)
171                         {
172                                 if (parameterData)
173                                         DBG_printf("Overflow by %i bytes. Parameter size is %i bytes but max %i bytes was expected. (%i bytes remaining)\n",
174                                                         overflow, parameterRealSize, parameterMaxSize , *size);
175
176                                 {
177                                         /* read overflowed buffer */
178                                         void* tmp = malloc(overflow);
179                                         getbufferchunk((rhnd->sock), size, tmp, overflow);
180                                         free(tmp);
181                                 }
182
183                         }
184                 }
185                 else if (0 != lng)
186                 {
187                         DBG_printf("popParameter (a): Expected 0 or 1 but got %i=0x%x (%i bytes remaining)\n", lng, lng, *size);
188                 }
189         }
190         else if (0 != lng)
191         {
192                 DBG_printf("popParameter (b): Expected 0 or 1 but got %i=0x%x (%i bytes remaining)\n", lng, lng, *size);
193         }
194 }
195
196 /**
197  * Convert parameter data from little endian after call to popParameter
198  */
199 #define popParameterInt16(rhnd,size, parameterData) \
200 popParameter(rhnd,size, parameterData, sizeof(u_int16_t)); \
201 if (parameterData) \
202         { *(u_int16_t*)parameterData = letoh16(*(u_int16_t*)parameterData); }
203
204 #define popParameterInt32(rhnd,size, parameterData) \
205 popParameter(rhnd,size, parameterData, sizeof(u_int32_t)); \
206 if (parameterData) \
207         { *(u_int32_t*)parameterData = letoh32(*(u_int32_t*)parameterData); }
208
209 void checkpassword(RAPIHandleP rhnd)
210 {
211         char buf[4];
212         /* Is the device protected ? */
213         /* ------------------------- */
214         if( (rhnd->lockbuffersize) != 0 )
215         {
216                 safe_write( (rhnd->sock), (rhnd->lockbuffer), (rhnd->lockbuffersize) );
217                 read( (rhnd->sock), buf, 1 );
218         }
219 }
220 /*=================================================================================================================*
221  *=================================================================================================================*
222  * RAPI - Global
223  *=================================================================================================================*
224  *=================================================================================================================*/
225
226 STDAPI_( DWORD ) CeGetSpecialFolderPath(RAPIHandleP rhnd, int nFolder, DWORD nBufferLength, LPWSTR lpBuffer )
227 {
228         long size = BUFSIZE;
229         long lng;
230         WCHAR * str;
231
232 //      checkpassword();
233
234         initBuf( (rhnd->buffer), size );
235         pushLong( (rhnd->buffer), size, 0x44 );                 /* Command */
236         pushLong( (rhnd->buffer), size, nFolder );              /* Parameter1 : the folder */
237         pushLong( (rhnd->buffer), size, nBufferLength );        /* Parameter2 : Buffer size that'll get the string */
238         DBG_printbuf( (rhnd->buffer) );
239         sendbuffer( (rhnd->sock), (rhnd->buffer) );
240
241         size = getbufferlen( (rhnd->sock) );
242
243         lng = getLong( (rhnd->sock), &size );
244         DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
245         lng = getLong( (rhnd->sock), &size );
246         DBG_printf( "long 2 : %ld (0x%08lx)\n", lng, lng );
247         lng = getLong( (rhnd->sock), &size );
248         DBG_printf( "string size : %ld (0x%08lx)\n", lng, lng );
249         str = getString( (rhnd->sock), &size, lng+1 );
250         DBG_printf( "string1 : %s\n", str );
251         if ( lpBuffer )
252         {
253                 memcpy( lpBuffer, str, MIN( ((lng+1)*sizeof(WCHAR) ), nBufferLength*sizeof(WCHAR) ) );
254         }
255         free(str);
256         return lng;
257 }
258
259 /* ================================================================================================================= */
260 /* ================================================================================================================= */
261 /*  RAPI - Registry */
262 /* ================================================================================================================= */
263 /* ================================================================================================================= */
264
265 /*
266 STDAPI_(LONG) CeRegDeleteKey( HKEY, LPCWSTR );
267 STDAPI_(LONG) CeRegDeleteValue( HKEY, LPCWSTR );
268 STDAPI_(LONG) CeRegQueryValueEx( HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD );
269 STDAPI_(LONG) CeRegSetValueEx( HKEY, LPCWSTR, DWORD, DWORD, LPBYTE, DWORD );
270 */
271
272 STDAPI_( LONG ) CeRegCreateKeyEx(RAPIHandleP rhnd, HKEY hKey, LPCWSTR lpszSubKey, DWORD Reserved, LPWSTR lpszClass, DWORD ulOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition )
273 {
274         long size = BUFSIZE;
275         long lng;
276         long errcode;
277         LONG result = ERROR_SUCCESS; /* May be result is really errcode. */
278
279         DBG_printf( "CeRegCreatKeyEx( hKey = 0x%08X, lpszSubKey = 0x%08X, Reserved = 0x%08X, lpszClass = 0x%08X, ulOptions = 0x%08X, samDesired = 0x%08X, lpSecurityAttributes = 0x%08X, phkResult = 0x%08X, lpdwDisposition = 0x%08X )\n",
280                     hKey, lpszSubKey, Reserved, lpszClass, ulOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition );
281
282         initBuf( (rhnd->buffer), size );
283         pushLong( (rhnd->buffer), size, 0x20 );                         /* Command */
284         pushLong( (rhnd->buffer), size, hKey );                         /* Parameter1 : */
285         pushLong( (rhnd->buffer), size, 0x01 );                         /* Parameter2 : */
286         pushLong( (rhnd->buffer), size, 1 + wcslen( lpszSubKey ) );     /* Parameter3 : */
287         pushString( (rhnd->buffer), size, lpszSubKey );                 /* Parameter4 : the path */
288         pushLong( (rhnd->buffer), size, 0x01 );                         /* Parameter5 : */
289         pushLong( (rhnd->buffer), size, 0x01 );                         /* Parameter6 : */
290         pushShort( (rhnd->buffer), size, 0x00 );                        /* Parameter7 : */
291
292         DBG_printbuf( (rhnd->buffer) );
293         sendbuffer( (rhnd->sock), (rhnd->buffer) );
294
295         size = getbufferlen( (rhnd->sock) );
296
297         errcode = getLong( (rhnd->sock), &size );
298         DBG_printf( "errpresent : %ld (0x%08lx)\n", errcode, errcode );
299         if ( errcode != 0 )
300         {
301                 errcode = getLong( (rhnd->sock), &size );
302                 DBG_printf( "errcode : %ld (0x%08lx)\n", errcode, errcode );
303         }
304         else
305         {
306                 lng = getLong( (rhnd->sock), &size );
307                 DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
308                 lng = getLong( (rhnd->sock), &size );
309                 DBG_printf( "long 2 : %ld (0x%08lx)\n", lng, lng );
310                 *phkResult = ( HKEY ) getLong( (rhnd->sock), &size );
311                 DBG_printf( "pHkey : %ld (0x%08lx)\n", *phkResult, *phkResult );
312                 *lpdwDisposition = ( DWORD ) getLong( (rhnd->sock), &size );
313                 DBG_printf( "lpdwDisposition : %ld (0x%08lx)\n", *lpdwDisposition, *lpdwDisposition );
314         }
315         return result;
316 }
317
318 STDAPI_( LONG ) CeRegOpenKeyEx(RAPIHandleP rhnd, HKEY hKey, LPCWSTR lpszSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult )
319 {
320         long size = BUFSIZE;
321         long errcode;
322
323         DBG_printf( "CeRegOpenKeyEx( hKey = 0x%08X, lpszSubKey = 0x%08X, ulOptions = 0x%08X, samDesired = 0x%08X, phkResult = 0x%08X )\n",
324                     hKey, lpszSubKey, ulOptions, samDesired, phkResult );
325
326         initBuf( (rhnd->buffer), size );
327         pushLong( (rhnd->buffer), size, 0x1E );         /* Command */
328         pushLong( (rhnd->buffer), size, hKey );                 /* Parameter1 : */
329 #if 0
330         pushLong( (rhnd->buffer), size, 0x01 );         /* Parameter2 : */
331         pushLong( (rhnd->buffer), size, 1 + wcslen( lpszSubKey ) );     /* Parameter3 : */
332         pushString( (rhnd->buffer), size, lpszSubKey );         /* Parameter4 : the path */
333 #else
334         pushParameter(rhnd,size, lpszSubKey, lpszSubKey ? (wcslen(lpszSubKey) + 1) * sizeof(WCHAR) : 0, 1);
335         pushLong( (rhnd->buffer), size, ulOptions);
336         pushLong( (rhnd->buffer), size, samDesired);
337         pushParameterInt32(rhnd,size, phkResult, 0);
338 #endif
339         DBG_printbuf( (rhnd->buffer) );
340         sendbuffer( (rhnd->sock), (rhnd->buffer) );
341
342         size = getbufferlen( (rhnd->sock) );
343
344         errcode = getLong( (rhnd->sock), &size );
345         DBG_printf( "errcode : %ld (0x%08lx)\n", errcode, errcode );
346
347         errcode = getLong( (rhnd->sock), &size );
348         DBG_printf( "errpresent : %ld (0x%08lx)\n", errcode, errcode );
349         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
350         DBG_printf( "long : %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
351         if ( errcode == 0 )
352         {
353                 *phkResult = ( HKEY ) getLong( (rhnd->sock), &size );
354                 DBG_printf( "pHkey : %ld (0x%08lx)\n", *phkResult, *phkResult );
355         }
356         return errcode;
357 }
358
359 STDAPI_( LONG ) CeRegCloseKey( RAPIHandleP rhnd,HKEY hKey )
360 {
361         long size = BUFSIZE;
362         long lng;
363         long result;
364
365         DBG_printf( "CeRegCloseKey( hKey = 0x%08X )\n",
366                     hKey );
367
368         initBuf( (rhnd->buffer), size );
369         pushLong( (rhnd->buffer), size, 0x21 );         /* Command */
370         pushLong( (rhnd->buffer), size, hKey );                 /* Parameter1 : */
371
372         DBG_printbuf( (rhnd->buffer) );
373         sendbuffer( (rhnd->sock), (rhnd->buffer) );
374         size = getbufferlen( (rhnd->sock) );
375
376         result = getLong( (rhnd->sock), &size );
377         DBG_printf( "result : %ld (0x%08lx)\n", result, result );
378         lng = getLong( (rhnd->sock), &size );
379         DBG_printf( "long 2 : %ld (0x%08lx)\n", lng, lng );
380         lng = getLong( (rhnd->sock), &size );
381         DBG_printf( "long 3 : %ld (0x%08lx)\n", lng, lng );
382         return result;
383 }
384
385 STDAPI_( LONG ) CeRegQueryInfoKey(RAPIHandleP rhnd, HKEY hKey, LPWSTR lpClass, LPDWORD lpcbClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcbMaxSubKeyLen, LPDWORD lpcbMaxClassLen, LPDWORD lpcValues, LPDWORD lpcbMaxValueNameLen, LPDWORD lpcbMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime )
386 {
387         long size = BUFSIZE;
388         long lng;
389         LONG result = ERROR_SUCCESS;
390
391 #if 0
392         DBG_printf( "CeRegQueryInfoKey( hKey = 0x%08X, lpClass = 0x%08X, lpcbClass = 0x%08X, lpReserved = 0x%08X, lpcSubKeys = 0x%08X, lpcbMaxSubKeyLen = 0x%08X, lpcbMaxClassLen = 0x%08X, lpcValues = 0x%08X, lpcbMaxValueNameLen = 0x%08X, lpcbMaxValueLen = 0x%08X, lpcbSecurityDescriptor = 0x%08X, lpftLastWriteTime = 0x%08X )\n",
393                     hKey, lpClass, lpcbClass, lpReserved, lpcSubKeys, lpcbMaxSubKeyLen, lpcbMaxClassLen, lpcValues, lpcbMaxValueNameLen, lpcbMaxValueLen, lpcbSecurityDescriptor, lpftLastWriteTime );
394 #endif
395
396         initBuf( (rhnd->buffer), size );
397         pushLong( (rhnd->buffer), size, 0x25 );         /* Command */
398         pushLong( (rhnd->buffer), size, hKey );         /* hKey */
399
400         pushParameter(rhnd,size, lpClass, lpcbClass ? *lpcbClass * sizeof(WCHAR): 0, 0);
401         pushParameterInt32(rhnd,size, lpcbClass, 1);
402         pushParameterInt32(rhnd,size, lpReserved, 0);
403         pushParameterInt32(rhnd,size, lpcSubKeys, 0);
404         pushParameterInt32(rhnd,size, lpcbMaxSubKeyLen, 0);
405         pushParameterInt32(rhnd,size, lpcbMaxClassLen, 0);
406         pushParameterInt32(rhnd,size, lpcValues, 0);
407         pushParameterInt32(rhnd,size, lpcbMaxValueNameLen, 0);
408         pushParameterInt32(rhnd,size, lpcbMaxValueLen, 0);
409         pushParameterInt32(rhnd,size, lpcbSecurityDescriptor, 1);
410         if (lpftLastWriteTime)
411         {
412                 lpftLastWriteTime->dwLowDateTime = (DWORD)htole32(lpftLastWriteTime->dwLowDateTime);
413                 lpftLastWriteTime->dwHighDateTime = (DWORD)htole32(lpftLastWriteTime->dwHighDateTime);
414         }
415         pushParameter(rhnd,size, lpftLastWriteTime, sizeof(FILETIME), 0);
416
417 /*      DBG_printbuf( (rhnd->buffer) );*/
418         sendbuffer( (rhnd->sock), (rhnd->buffer) );
419
420         size = getbufferlen( (rhnd->sock) );
421
422         result = lng = getLong( (rhnd->sock), &size );
423         (rhnd->_lasterror) = lng = getLong( (rhnd->sock), &size );
424
425         if (ERROR_SUCCESS == result)
426         {
427                 popParameter(rhnd,&size, lpClass, lpcbClass ? *lpcbClass: 0);
428                 popParameterInt32(rhnd,&size, lpcbClass);
429                 popParameterInt32(rhnd,&size, lpReserved);
430                 popParameterInt32(rhnd,&size, lpcSubKeys);
431                 popParameterInt32(rhnd,&size, lpcbMaxSubKeyLen);
432                 popParameterInt32(rhnd,&size, lpcbMaxClassLen);
433                 popParameterInt32(rhnd,&size, lpcValues);
434                 popParameterInt32(rhnd,&size, lpcbMaxValueNameLen);
435                 popParameterInt32(rhnd,&size, lpcbMaxValueLen);
436                 popParameterInt32(rhnd,&size, lpcbSecurityDescriptor);
437                 popParameter(rhnd,&size, lpftLastWriteTime, sizeof(FILETIME));
438                 if (lpftLastWriteTime)
439                 {
440                         lpftLastWriteTime->dwLowDateTime = (DWORD)letoh32(lpftLastWriteTime->dwLowDateTime);
441                         lpftLastWriteTime->dwHighDateTime = (DWORD)letoh32(lpftLastWriteTime->dwHighDateTime);
442                 }
443         }
444
445         if ( size > 0 )
446         {
447                 DBG_printf( "size : %d\n", size );
448 /*              flushbuffer( (rhnd->sock) );*/
449         }
450         return result;
451 }
452
453 STDAPI_( LONG ) CeRegEnumValue(RAPIHandleP rhnd, HKEY hKey, DWORD dwIndex, LPWSTR lpszValueName, LPDWORD lpcbValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData )
454 {
455         LONG result = ERROR_SUCCESS;
456         long size = BUFSIZE;
457
458 #if 0
459         DBG_printf( "CeRegEnumValue( hKey = 0x%08X, dwIndex = 0x%08X, lpszValueName = 0x%08X, lpcbValueName = 0x%08X, lpReserved = 0x%08X, lpType = 0x%08X, lpData = 0x%08X, lpcbData = 0x%08X )\n",
460                     hKey, dwIndex, lpszValueName, ( *lpcbValueName ), lpReserved, ( *lpType ), ( *lpData ), ( *lpcbData ) );
461 #endif
462
463         /* maybe check more parameters */
464         if (!lpcbValueName || lpReserved)
465                 return 87; /* ERROR_INVALID_PARAMETER */
466                 
467         initBuf( (rhnd->buffer), size );
468         pushLong( (rhnd->buffer), size, 0x23 );         /* Command */
469         pushLong( (rhnd->buffer), size, hKey );         /* Parameter1 : */
470         pushLong( (rhnd->buffer), size, dwIndex );      /* Parameter2 : */
471
472         pushParameter(rhnd,size, lpszValueName, lpcbValueName ? *lpcbValueName * sizeof(WCHAR): 0, 0);
473         pushParameterInt32(rhnd,size, lpcbValueName, 1);
474         pushParameterInt32(rhnd,size, lpReserved, 1);
475         pushParameterInt32(rhnd,size, lpType, 1);
476         pushParameter(rhnd,size, lpData, lpcbData ? *lpcbData : 0, 0);
477         pushParameterInt32(rhnd,size, lpcbData, 1);
478
479 /*      DBG_printbuf( (rhnd->buffer) );*/
480         sendbuffer( (rhnd->sock), (rhnd->buffer) );
481
482         size = getbufferlen( (rhnd->sock) );
483         
484         result = getLong( (rhnd->sock), &size ); 
485         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
486
487         if (ERROR_SUCCESS == result)
488         {
489                 /* here comes a result again! */
490                 result = getLong( (rhnd->sock), &size );
491         }
492                 
493         if (ERROR_SUCCESS == result)
494         {
495                 popParameter(rhnd,&size, lpszValueName, lpcbValueName ? *lpcbValueName : 0);
496                 popParameterInt32(rhnd,&size, lpcbValueName);
497                 popParameterInt32(rhnd,&size, lpType);
498                 popParameter(rhnd,&size, lpData, lpcbData ? *lpcbData : 0);
499                 popParameterInt32(rhnd,&size, lpcbData);
500         }
501
502         if ( size > 0 )
503         {
504                 DBG_printf( "size : %d\n", size );
505 /*              flushbuffer( (rhnd->sock) );*/
506         }
507         return result;
508 }
509
510 STDAPI_( LONG ) CeRegEnumKeyEx(RAPIHandleP rhnd, HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD lpcbName, LPDWORD lpReserved, LPWSTR lpClass, LPDWORD lpcbClass, PFILETIME lpftLastWriteTime )
511 {
512         long size = BUFSIZE;
513         long lng;
514         WCHAR * str;
515         int i;
516         long errcode;
517         long strsz;
518         long maxsz;
519
520         DBG_printf( "CeRegEnumKeyEx( hKey = 0x%08X, dwIndex = 0x%08X, lpcbName = 0x%08X, lpReserved = 0x%08X, lpClass = 0x%08X, lpcbClass = 0x%08X, lpftLastWriteTime = 0x%08X )\n",
521                     hKey, dwIndex, lpName, lpcbName ? ( (void*)*lpcbName ) : lpcbName, lpReserved, lpClass, lpcbClass ? ( (void*)*lpcbClass ) : lpcbClass, lpftLastWriteTime );
522
523         initBuf( (rhnd->buffer), size );
524         pushLong( (rhnd->buffer), size, 0x1F );         /* Command */
525         pushLong( (rhnd->buffer), size, hKey );         /* Parameter1 : */
526         pushLong( (rhnd->buffer), size, dwIndex );      /* Parameter2 : */
527         pushLong( (rhnd->buffer), size, 0x01 );         /* Parameter3 : */
528         pushLong( (rhnd->buffer), size, 0x0202 );       /* Parameter4 : */
529         pushLong( (rhnd->buffer), size, 0x00 );         /* Parameter5 : */
530         pushLong( (rhnd->buffer), size, 0x01 );         /* Parameter6 : */
531         pushLong( (rhnd->buffer), size, 0x04 );         /* Parameter7 : */
532         pushLong( (rhnd->buffer), size, 0x01 );         /* Parameter8 : */
533         pushLong( (rhnd->buffer), size, lpcbName ? ( *lpcbName ) : 0 );         /* Parameter9 : */
534         pushLong( (rhnd->buffer), size, 0x00 );         /* Parameter10 : */
535         pushLong( (rhnd->buffer), size, 0x00 );         /* Parameter11 : */
536         pushLong( (rhnd->buffer), size, 0x00 );         /* Parameter12 : */
537         pushLong( (rhnd->buffer), size, 0x00 );         /* Parameter13 : */
538         DBG_printbuf( (rhnd->buffer) );
539         sendbuffer( (rhnd->sock), (rhnd->buffer) );
540
541         size = getbufferlen( (rhnd->sock) );
542         lng = getLong( (rhnd->sock), &size );
543         DBG_printf( "long : %ld (0x%08lx)\n", lng, lng );
544         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
545         DBG_printf( "long : %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
546         errcode = getLong( (rhnd->sock), &size );
547         DBG_printf( "errcode : %ld (0x%08lx)\n", errcode, errcode );
548         lng = getLong( (rhnd->sock), &size );
549         DBG_printf( "long : %ld (0x%08lx)\n", lng, lng );
550         if ( errcode == 0 )
551         {
552                 strsz = getLong( (rhnd->sock), &size );
553                 DBG_printf( "long : %ld (0x%08lx)\n", strsz, strsz );
554                 maxsz = 0;
555                 if ( lpcbName != NULL )
556                 {
557                         maxsz = ( *lpcbName );
558                         ( *lpcbName ) = strsz - 1;
559                 }
560                 lng = getLong( (rhnd->sock), &size );
561                 DBG_printf( "long : %ld (0x%08lx)\n", lng, lng );
562                 str = getString( (rhnd->sock), &size, strsz >> 1 );
563                 DBG_printf( "string1 : %s\n", str );
564                 if ( ( lpName != NULL ) )
565                 {
566                         memcpy( lpName, str, MIN( strsz, maxsz ) );
567                 }
568                 free(str);
569                 for ( i = 0; i < 7; i++ )
570                 {
571                         lng = getLong( (rhnd->sock), &size );
572                         DBG_printf( "long %d : %ld (0x%08lx)\n", i, lng, lng );
573                 }
574         }
575
576         return errcode;
577 }
578
579 /* ================================================================================================================= */
580 /* ================================================================================================================= */
581 /*  RAPI - Tests */
582 /* ================================================================================================================= */
583 /* ================================================================================================================= */
584
585 #if 0
586 DWORD CeTestSec1()
587 {
588         long size=BUFSIZE;
589         long lng;
590         int result;
591         long index;
592  
593         initBuf( (rhnd->buffer), size );
594         pushLong( (rhnd->buffer), size, 0x27 ); /* Command */
595         pushLong( (rhnd->buffer), size, 0x80000002 );           /* Parameter1 : */
596         pushLong( (rhnd->buffer), size, 0x01 ); /* Parameter2 : */
597         pushLong( (rhnd->buffer), size, 0x20 ); /* Parameter3 : */
598         pushString( (rhnd->buffer), size, "Comm\\SecurityProviders\\SCHANNEL" );        /* Parameter4 : the path */
599         pushLong( (rhnd->buffer), size, 0x01 ); /* Parameter2 : */
600         pushLong( (rhnd->buffer), size, 0x01 ); /* Parameter2 : */
601         pushShort( (rhnd->buffer), size, 0x00 );        /* Parameter2 : */
602  
603         DBG_printbuf( (rhnd->buffer) );
604         sendbuffer( (rhnd->sock), (rhnd->buffer) );
605         result = readbuffer( (rhnd->sock), (rhnd->buffer), size );
606         DBG_printbuf( (rhnd->buffer) );
607         index = 0;
608         return 2*lng;
609 }
610
611 DWORD CeTest0()
612 {
613         long size=BUFSIZE;
614         long lng;
615         int result;
616         long index;
617         
618         initBuf( (rhnd->buffer), size );
619         pushLong( (rhnd->buffer), size, 0x1E ); /* Command */
620         pushLong( (rhnd->buffer), size, 0x80000000 );           /* Parameter1 : */
621         pushLong( (rhnd->buffer), size, 0x01 ); /* Parameter2 : */
622         pushLong( (rhnd->buffer), size, 0x27 ); /* Parameter3 : */
623         pushString( (rhnd->buffer), size, "{000214A0-0000-0000-C000-000000000046}" );   /* Parameter3 : the path */
624  
625         DBG_printbuf( (rhnd->buffer) );
626         sendbuffer( (rhnd->sock), (rhnd->buffer) );
627         result = readbuffer( (rhnd->sock), (rhnd->buffer), size );
628         DBG_printbuf( (rhnd->buffer) );
629         index = 0;
630         return 2*lng;
631 }
632 #endif
633
634 /* ================================================================================================================= */
635 /* ================================================================================================================= */
636 /*  RAPI - Files */
637 /* ================================================================================================================= */
638 /* ================================================================================================================= */
639
640 STDAPI_( BOOL ) CeFindAllFiles(RAPIHandleP rhnd, LPCWSTR szPath, DWORD dwFlags, LPDWORD lpdwFoundCount, LPLPCE_FIND_DATA ppFindDataArray )
641 {
642         long size = BUFSIZE;
643         long lng;
644         WCHAR * str;
645         long stlen = 0;
646         long i;
647         CE_FIND_DATA *ptr;
648
649         DBG_printf( "CeFindAllFiles : szPath = 0x%08X, dwFlags = 0x%08X, lpdwFoundCount = 0x%08X, ppFindDataArray = 0x%08X\n", szPath, dwFlags, lpdwFoundCount, ppFindDataArray );
650
651 //      checkpassword();
652
653         initBuf( (rhnd->buffer), size );
654         pushLong( (rhnd->buffer), size, 0x09 );                         /* Command */
655         pushLong( (rhnd->buffer), size, 0x01 );                         /* Parameter1 : */
656         pushLong( (rhnd->buffer), size, 1 + wcslen( szPath ) );         /* Parameter2 : */
657         pushString( (rhnd->buffer), size, szPath );                     /* Parameter3 : the path */
658         pushLong( (rhnd->buffer), size, dwFlags );                      /* Parameter4 : Flags ? */
659         DBG_printbuf( (rhnd->buffer) );
660         sendbuffer( (rhnd->sock), (rhnd->buffer) );
661
662         size = getbufferlen( (rhnd->sock) );
663         lng = getLong( (rhnd->sock), &size );
664         DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
665         lng = getLong( (rhnd->sock), &size );
666         DBG_printf( "long 2 (nb answer) : %ld (0x%08lx)\n", lng, lng );
667         if ( lpdwFoundCount )
668         {
669                 *lpdwFoundCount = lng;
670         }
671         if ( ppFindDataArray )
672         {
673                 DBG_printf( "Before allocation\n" );
674                 *ppFindDataArray = ( LPCE_FIND_DATA ) calloc( lng, sizeof( CE_FIND_DATA ) );
675                 DBG_printf( "After allocation : *ppFindDataArray = %08X\n", *ppFindDataArray );
676                 if ( ( *ppFindDataArray ) )
677                 {
678                         for ( i = 0; i < lng; i++ )
679                         {
680                                 ptr = &( ( *ppFindDataArray ) [ i ] );
681                                 DBG_printf( "i=%d : ptr=%08X\n", i, ptr );
682                                 if ( dwFlags & FAF_NAME )
683                                 {
684                                         stlen = getLong( (rhnd->sock), &size );
685                                         DBG_printf( "string size : %ld (0x%08lx)\n", stlen, stlen );
686                                 }
687                                 if ( dwFlags & FAF_ATTRIBUTES )
688                                 {
689                                         ptr->dwFileAttributes = getLong( (rhnd->sock), &size );
690                                         DBG_printf( "ptr->dwFileAttributes : %ld (0x%08lx)\n", ptr->dwFileAttributes, ptr->dwFileAttributes );
691                                 }
692                                 if ( dwFlags & FAF_CREATION_TIME )
693                                 {
694                                         ptr->ftCreationTime.dwLowDateTime = getLong( (rhnd->sock), &size );
695                                         DBG_printf( "ptr->ftCreationTime.dwLowDateTime : %ld (0x%08lx)\n", ptr->ftCreationTime.dwLowDateTime, ptr->ftCreationTime.dwLowDateTime );
696                                         ptr->ftCreationTime.dwHighDateTime = getLong( (rhnd->sock), &size );
697                                         DBG_printf( "ptr->ftCreationTime.dwHighDateTime : %ld (0x%08lx)\n", ptr->ftCreationTime.dwHighDateTime, ptr->ftCreationTime.dwHighDateTime );
698                                 }
699                                 if ( dwFlags & FAF_LASTACCESS_TIME )
700                                 {
701                                         ptr->ftLastAccessTime.dwLowDateTime = getLong( (rhnd->sock), &size );
702                                         DBG_printf( "ptr->ftLastAccessTime.dwLowDateTime : %ld (0x%08lx)\n", ptr->ftLastAccessTime.dwLowDateTime, ptr->ftLastAccessTime.dwLowDateTime );
703                                         ptr->ftLastAccessTime.dwHighDateTime = getLong( (rhnd->sock), &size );
704                                         DBG_printf( "ptr->ftLastAccessTime.dwHighDateTime : %ld (0x%08lx)\n", ptr->ftLastAccessTime.dwHighDateTime, ptr->ftLastAccessTime.dwHighDateTime );
705                                 }
706                                 if ( dwFlags & FAF_LASTWRITE_TIME )
707                                 {
708                                         ptr->ftLastWriteTime.dwLowDateTime = getLong( (rhnd->sock), &size );
709                                         DBG_printf( "ptr->ftLastWriteTime.dwLowDateTime : %ld (0x%08lx)\n", ptr->ftLastWriteTime.dwLowDateTime, ptr->ftLastWriteTime.dwLowDateTime );
710                                         ptr->ftLastWriteTime.dwHighDateTime = getLong( (rhnd->sock), &size );
711                                         DBG_printf( "ptr->ftLastWriteTime.dwHighDateTime : %ld (0x%08lx)\n", ptr->ftLastWriteTime.dwHighDateTime, ptr->ftLastWriteTime.dwHighDateTime );
712                                 }
713                                 if ( dwFlags & FAF_SIZE_HIGH )
714                                 {
715                                         ptr->nFileSizeHigh = getLong( (rhnd->sock), &size );
716                                         DBG_printf( "ptr->nFileSizeHigh : %ld (0x%08lx)\n", ptr->nFileSizeHigh, ptr->nFileSizeHigh );
717                                 }
718                                 if ( dwFlags & FAF_SIZE_LOW )
719                                 {
720                                         ptr->nFileSizeLow = getLong( (rhnd->sock), &size );
721                                         DBG_printf( "ptr->nFileSizeLow : %ld (0x%08lx)\n", ptr->nFileSizeLow, ptr->nFileSizeLow );
722                                 }
723                                 if ( dwFlags & FAF_OID )
724                                 {
725                                         ptr->dwOID = getLong( (rhnd->sock), &size );
726                                         DBG_printf( "ptr->dwOID : %ld (0x%08lx)\n", ptr->dwOID, ptr->dwOID );
727                                 }
728                                 if ( dwFlags & FAF_NAME )
729                                 {
730                                         str = getString( (rhnd->sock), &size, stlen );
731                                         memcpy( ptr->cFileName, str, MAX_PATH );
732                                         DBG_printf( "ptr->cFileName : %s\n", ptr->cFileName );
733                                         free(str);
734                                 }
735                         }
736                 }
737         }
738         return TRUE;
739 }
740
741 STDAPI_( HANDLE ) CeFindFirstFile(RAPIHandleP rhnd, LPCWSTR lpFileName, LPCE_FIND_DATA lpFileFindData )
742 {
743         long size = BUFSIZE;
744         long lng;
745         HANDLE result;
746         size_t stlen;
747         /* CEDB_FIND_DATA *ptr; */
748
749         DBG_printf( "CeFindFirstFile( lpFileName = 0x%08X, lpFileFindData = 0x%08X )\n",
750                     lpFileName, lpFileFindData );
751
752         initBuf( (rhnd->buffer), size );
753         DBG_printf(" line : %d\n", __LINE__ );
754         pushLong( (rhnd->buffer), size, 0x00 );                 /* Command */
755         DBG_printf(" line : %d\n", __LINE__ );
756         pushLong( (rhnd->buffer), size, 0x01 );                 /* Parameter1 : */
757         DBG_printf(" line : %d\n", __LINE__ );
758         if ( lpFileName )
759         {
760                 stlen = wcslen( lpFileName );
761         }
762         else
763         {
764                 stlen = -1;
765         }
766         DBG_printf( "size : %d\n", stlen );
767         pushLong( (rhnd->buffer), size, 1 + stlen );            /* Parameter2 : Flags ? */
768         pushString( (rhnd->buffer), size, lpFileName );         /* Parameter3 : the path */
769         DBG_printbuf( (rhnd->buffer) );
770         sendbuffer( (rhnd->sock), (rhnd->buffer) );
771
772         size = getbufferlen( (rhnd->sock) );
773
774         lng = getLong( (rhnd->sock), &size );
775         DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
776         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
777         DBG_printf( "long 2 (errorcode?): %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
778         result = ( HANDLE ) getLong( (rhnd->sock), &size );
779         DBG_printf( "long 3 : (size=%d) HANDLE %ld (0x%08lx)\n", size, result, result );
780         lng = getLong( (rhnd->sock), &size );
781         DBG_printf( "long 4 : %ld (0x%08lx)\n", lng, lng );
782         if ( lpFileFindData )
783         {
784                 lpFileFindData->dwFileAttributes = getLong( (rhnd->sock), &size );
785                 getbufferchunk( (rhnd->sock), &size, &( lpFileFindData->ftCreationTime ), sizeof( FILETIME ) );
786                 getbufferchunk( (rhnd->sock), &size, &( lpFileFindData->ftLastAccessTime ), sizeof( FILETIME ) );
787                 getbufferchunk( (rhnd->sock), &size, &( lpFileFindData->ftLastWriteTime ), sizeof( FILETIME ) );
788                 lpFileFindData->nFileSizeHigh = getLong( (rhnd->sock), &size );
789                 lpFileFindData->nFileSizeLow = getLong( (rhnd->sock), &size );
790                 lpFileFindData->dwOID = getLong( (rhnd->sock), &size );
791                 memset( &( lpFileFindData->cFileName ), 0, MAX_PATH );
792                 getbufferchunk( (rhnd->sock), &size, &( lpFileFindData->cFileName ), size );
793         }
794
795         DBG_printf( "size : %d\n", size );
796         if ( size > 0 )
797         {
798                 flushbuffer( (rhnd->sock) );
799         }
800         DBG_printf( "long 5 : %ld (0x%08lx)\n", lpFileFindData->dwFileAttributes, lpFileFindData->dwFileAttributes );
801         return result;
802 }
803
804 STDAPI_( BOOL ) CeFindNextFile(RAPIHandleP rhnd, HANDLE hFindFile,  /*LPWIN32_FIND_DATA ?*/LPCE_FIND_DATA lpFileFindData )
805 {
806         long size = BUFSIZE;
807         long lng;
808         int result;
809         /* CEDB_FIND_DATA *ptr; */
810
811         DBG_printf( "CeFindNextFile( hFindFile = 0x%08X, lpFileFindData = 0x%08X )\n",
812                     hFindFile, lpFileFindData );
813
814         initBuf( (rhnd->buffer), size );
815         pushLong( (rhnd->buffer), size, 0x01 );                 /* Command */
816         pushLong( (rhnd->buffer), size, ( long ) hFindFile );   /* Parameter1 : */
817         DBG_printbuf( (rhnd->buffer) );
818         sendbuffer( (rhnd->sock), (rhnd->buffer) );
819
820         size = getbufferlen( (rhnd->sock) );
821
822         lng = getLong( (rhnd->sock), &size );
823         DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
824         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
825         DBG_printf( "long 2 (errorcode?): %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
826         lng = getLong( (rhnd->sock), &size );
827         DBG_printf( "long 3 (size=%d): %ld (0x%08lx)\n", size, lng, lng );
828         lng = getLong( (rhnd->sock), &size );
829         DBG_printf( "long 4 : %ld (0x%08lx)\n", lng, lng );
830         if ( lpFileFindData )
831         {
832                 lpFileFindData->dwFileAttributes = getLong( (rhnd->sock), &size );
833                 getbufferchunk( (rhnd->sock), &size, &( lpFileFindData->ftCreationTime ), sizeof( FILETIME ) );
834                 getbufferchunk( (rhnd->sock), &size, &( lpFileFindData->ftLastAccessTime ), sizeof( FILETIME ) );
835                 getbufferchunk( (rhnd->sock), &size, &( lpFileFindData->ftLastWriteTime ), sizeof( FILETIME ) );
836                 lpFileFindData->nFileSizeHigh = getLong( (rhnd->sock), &size );
837                 lpFileFindData->nFileSizeLow = getLong( (rhnd->sock), &size );
838                 lpFileFindData->dwOID = getLong( (rhnd->sock), &size );
839                 memset( &( lpFileFindData->cFileName ), 0, MAX_PATH );
840                 getbufferchunk( (rhnd->sock), &size, &( lpFileFindData->cFileName ), size );
841         }
842         DBG_printf( "size : %d\n", size );
843
844         if ( size > 0 )
845         {
846                 flushbuffer( (rhnd->sock) );
847         }
848         result = ( (rhnd->_lasterror) == 0 );
849         return result;
850 }
851
852 STDAPI_( BOOL ) CeFindClose(RAPIHandleP rhnd, HANDLE hFindFile )
853 {
854         long size = BUFSIZE;
855         long lng;
856
857         DBG_printf( "CeFindClose()\n" );
858
859         initBuf( (rhnd->buffer), size );
860         pushLong( (rhnd->buffer), size, 0x02 );                 /* Command */
861         pushLong( (rhnd->buffer), size, ( long ) hFindFile );   /* Parameter1 : */
862         DBG_printbuf( (rhnd->buffer) );
863         sendbuffer( (rhnd->sock), (rhnd->buffer) );
864
865         size = getbufferlen( (rhnd->sock) );
866         lng = getLong( (rhnd->sock), &size );
867         DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
868         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
869         DBG_printf( "long 2 (lasterror): %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
870         lng = getLong( (rhnd->sock), &size );
871         DBG_printf( "long 3 : %ld (0x%08lx)\n", lng, lng );
872
873         if ( size > 0 )
874         {
875                 DBG_printf( "size : %d\n", size );
876                 flushbuffer( (rhnd->sock) );
877         }
878
879         return lng;
880 }
881
882 STDAPI_( HANDLE ) CeCreateFile(RAPIHandleP rhnd, LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile )
883 {
884         long size = BUFSIZE;
885         long lng;
886         HANDLE result;
887         long stlen;
888
889         DBG_printf( "CeCreateFile( lpFileName = 0x%08X, dwDesiredAccess = 0x%08X, dwShareMode = 0x%08X )\n",
890                     lpFileName, dwDesiredAccess, dwShareMode );
891
892 //      checkpassword();
893
894         initBuf( (rhnd->buffer), size );
895         pushLong( (rhnd->buffer), size, 0x05 );                         /* Command */
896         pushLong( (rhnd->buffer), size, dwDesiredAccess );              /* Parameter1 */
897         pushLong( (rhnd->buffer), size, dwShareMode );                  /* Parameter2 */
898         pushLong( (rhnd->buffer), size, dwCreationDisposition );        /* Parameter3 */
899         pushLong( (rhnd->buffer), size, dwFlagsAndAttributes );         /* Parameter4 */
900         pushLong( (rhnd->buffer), size, ( long ) hTemplateFile );       /* Parameter5 */
901         pushLong( (rhnd->buffer), size, 1 );                            /* Parameter6 */
902         stlen = wcslen( lpFileName );
903         pushLong( (rhnd->buffer), size, 1 + stlen );                    /* Parameter7 */
904         pushString( (rhnd->buffer), size, lpFileName );                 /* Parameter8 */
905         DBG_printbuf( (rhnd->buffer) );
906         sendbuffer( (rhnd->sock), (rhnd->buffer) );
907
908         size = getbufferlen( (rhnd->sock) );
909
910         lng = getLong( (rhnd->sock), &size );
911         DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
912         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
913         DBG_printf( "long 2 (errorcode?): %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
914         result = ( HANDLE ) getLong( (rhnd->sock), &size );
915         DBG_printf( "long 3 (HANDLE): %ld (0x%08lx)\n", result, result );
916
917         if ( size > 0 )
918         {
919                 flushbuffer( (rhnd->sock) );
920         }
921
922         return result;
923 }
924
925 STDAPI_( BOOL ) CeReadFile(RAPIHandleP rhnd, HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped )
926 {
927         long size = BUFSIZE;
928         long lng;
929         BOOL result;
930         /* CEDB_FIND_DATA *ptr; */
931
932         DBG_printf( "CeReadFile( hFile = 0x%08X, nNumberOfBytesToRead = 0x%08X )\n",
933                     hFile, nNumberOfBytesToRead );
934
935         initBuf( (rhnd->buffer), size );
936         pushLong( (rhnd->buffer), size, 0x06 );                 /* Command */
937         pushLong( (rhnd->buffer), size, ( long ) hFile );       /* Parameter1 */
938         pushLong( (rhnd->buffer), size, 0x01 );                 /* Parameter2 */
939         pushLong( (rhnd->buffer), size, nNumberOfBytesToRead ); /* Parameter3 */
940         pushLong( (rhnd->buffer), size, 0x00 );                 /* Parameter4 */
941         DBG_printbuf( (rhnd->buffer) );
942         sendbuffer( (rhnd->sock), (rhnd->buffer) );
943
944         size = getbufferlen( (rhnd->sock) );
945
946         lng = getLong( (rhnd->sock), &size );
947         DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
948         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
949         DBG_printf( "long 2 (errorcode?): %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
950         result = ( BOOL ) getLong( (rhnd->sock), &size );
951         DBG_printf( "long 3 (BOOL): %ld (0x%08lx)\n", result, result );
952         lng = getLong( (rhnd->sock), &size );
953         DBG_printf( "long 4 (size): %ld (0x%08lx)\n", lng, lng );
954
955         if ( lpNumberOfBytesRead )
956         {
957                 *lpNumberOfBytesRead = lng;
958         }
959         if ( ( lpBuffer ) && ( lng > 0 ) )
960         {
961                 getbufferchunk( (rhnd->sock), &size, lpBuffer, lng );
962         }
963
964         if ( size > 0 )
965         {
966                 DBG_printf( "Size != 0 : size=%d\n", size );
967                 flushbuffer( (rhnd->sock) );
968         }
969
970         return result;
971 }
972
973 STDAPI_( BOOL ) CeWriteFile(RAPIHandleP rhnd, HANDLE hFile, LPVOID lpBuffer,
974                              DWORD nNumberOfBytesToWrite,
975                              LPDWORD lpNumberOfBytesWritten, 
976                              LPOVERLAPPED lpOverlapped )
977 {
978         long size = BUFSIZE;
979         long lng;
980         BOOL result;
981         unsigned long buflen;
982
983         
984         /* CEDB_FIND_DATA *ptr; */
985
986         DBG_printf( "CeWriteFile( hFile = 0x%08X, nNumberOfBytesToWrite = 0x%08X )\n",
987                     hFile, nNumberOfBytesToWrite );
988
989         initBuf( (rhnd->buffer), size );
990         pushLong( (rhnd->buffer), size, 0x07 );                         /* Command */
991         pushLong( (rhnd->buffer), size, ( long ) hFile );               /* Parameter1 */
992         pushLong( (rhnd->buffer), size, 0x01 );                         /* Parameter2 */
993         pushLong( (rhnd->buffer), size, nNumberOfBytesToWrite );        /* Parameter3 */
994         
995         buflen=_getbufferlen((rhnd->buffer));
996         _setbufferlen( (rhnd->buffer), buflen + nNumberOfBytesToWrite + 4);
997         
998         (void) safe_write((rhnd->sock), (void *) (rhnd->buffer), buflen + 4);
999
1000         (void) safe_write((rhnd->sock), lpBuffer, nNumberOfBytesToWrite);
1001         lng=0;
1002         (void) safe_write((rhnd->sock), (void *) &lng, sizeof(lng)); /*  ??? continue ??? */
1003         
1004         size = getbufferlen( (rhnd->sock) );
1005
1006         lng = getLong( (rhnd->sock), &size );
1007         DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
1008         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
1009         DBG_printf( "long 2 (errorcode?): %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
1010
1011         result = ( BOOL ) getLong( (rhnd->sock), &size );
1012         DBG_printf( "long 3 (BOOL): %ld (0x%08lx)\n", result, result );
1013         lng = getLong( (rhnd->sock), &size );
1014         DBG_printf( "long 4 (size): %ld (0x%08lx)\n", lng, lng );
1015
1016         if ( lpNumberOfBytesWritten )
1017         {
1018                 *lpNumberOfBytesWritten = lng;
1019         }
1020         if ( size > 0 )
1021         {
1022                 flushbuffer( (rhnd->sock) );
1023         }
1024
1025         return result;
1026 }
1027
1028 /* ================================================================================================================= */
1029 /* ================================================================================================================= */
1030 /*  RAPI - Databases */
1031 /* ================================================================================================================= */
1032 /* ================================================================================================================= */
1033
1034
1035 STDAPI_( BOOL ) CeFindAllDatabases(RAPIHandleP rhnd, DWORD dwDbaseType, WORD wFlags, LPWORD cFindData, LPLPCEDB_FIND_DATA ppFindData )
1036 {
1037         long size = BUFSIZE;
1038         long lng;
1039         WCHAR * str;
1040         long stlen = 0;
1041         long i, j;
1042         WORD wrd;
1043         CEDB_FIND_DATA *ptr;
1044
1045 //      checkpassword();
1046
1047         DBG_printf( "CeFindAllDatabases( dwDbaseType = 0x%08X, wFlags = 0x%04X, cFindData = 0x%08X, ppFindData = 0x%08X )\n",
1048                     dwDbaseType, wFlags, cFindData, ppFindData );
1049
1050         initBuf( (rhnd->buffer), size );
1051         pushLong( (rhnd->buffer), size, 0x2C );         /* Command */
1052         pushLong( (rhnd->buffer), size, dwDbaseType );  /* Parameter1 : */
1053         pushShort( (rhnd->buffer), size, wFlags );      /* Parameter2 : Flags ? */
1054         DBG_printbuf( (rhnd->buffer) );
1055         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1056
1057         size = getbufferlen( (rhnd->sock) );
1058         lng = getLong( (rhnd->sock), &size );
1059         DBG_printf( "long 1 (errorcode?): %ld (0x%08lx)\n", lng, lng );
1060         wrd = getShort( (rhnd->sock), &size );
1061         DBG_printf( "word 1 : %d (0x%08lx)\n", wrd, wrd );
1062         if ( cFindData )
1063         {
1064                 *cFindData = wrd;
1065         }
1066         if ( ppFindData && ( wrd > 0 ) )
1067         {
1068                 DBG_printf( "Before allocation\n" );
1069                 *ppFindData = ( LPCEDB_FIND_DATA ) calloc( wrd, sizeof( CEDB_FIND_DATA ) );
1070                 DBG_printf( "After allocation : *ppFindData = %08X\n", *ppFindData );
1071                 if ( ( *ppFindData ) )
1072                 {
1073                         for ( i = 0; i < wrd; i++ )
1074                         {
1075                                 ptr = &( ( *ppFindData ) [ i ] );
1076                                 DBG_printf( "i=%d : ptr=%08X\n", i, ptr );
1077                                 if ( wFlags & FAD_OID )
1078                                 {
1079                                         ptr->OidDb = getLong( (rhnd->sock), &size );
1080                                         DBG_printf( "OidDb : %ld (0x%08lx)\n", ptr->OidDb, ptr->OidDb );
1081                                 }
1082                                 if ( wFlags & FAD_NAME )
1083                                 {
1084                                         stlen = getLong( (rhnd->sock), &size );
1085                                         DBG_printf( "string size : %ld (0x%08lx)\n", stlen, stlen );
1086                                 }
1087                                 if ( wFlags & FAD_FLAGS )
1088                                 {
1089                                         ptr->DbInfo.dwFlags = getLong( (rhnd->sock), &size );
1090                                         DBG_printf( "dwFlags : %ld (0x%08lx)\n", ptr->DbInfo.dwFlags, ptr->DbInfo.dwFlags );
1091                                 }
1092                                 if ( wFlags & FAD_NAME )
1093                                 {
1094                                         str = getString( (rhnd->sock), &size, stlen );
1095                                         memcpy( ptr->DbInfo.szDbaseName, str, sizeof( WCHAR ) * ( CEDB_MAXDBASENAMELEN > ( stlen ) ? CEDB_MAXDBASENAMELEN : ( stlen ) ) );
1096                                         DBG_printf( "ptr->DbInfo.szDbaseName : %s\n", ptr->DbInfo.szDbaseName );
1097                                         free(str);
1098                                 }
1099                                 if ( wFlags & FAD_TYPE )
1100                                 {
1101                                         ptr->DbInfo.dwDbaseType = getLong( (rhnd->sock), &size );
1102                                         DBG_printf( "dwDbaseType : %ld (0x%08lx)\n", ptr->DbInfo.dwDbaseType, ptr->DbInfo.dwDbaseType );
1103                                 }
1104                                 if ( wFlags & FAD_NUM_RECORDS )
1105                                 {
1106                                         ptr->DbInfo.wNumRecords = getShort( (rhnd->sock), &size );
1107                                         DBG_printf( "wNumRecords : %ld (0x%08lx)\n", ptr->DbInfo.wNumRecords, ptr->DbInfo.wNumRecords );
1108                                 }
1109                                 if ( wFlags & FAD_NUM_SORT_ORDER )
1110                                 {
1111                                         ptr->DbInfo.wNumSortOrder = getShort( (rhnd->sock), &size );
1112                                         DBG_printf( "wNumSortOrder : %ld (0x%08lx)\n", ptr->DbInfo.wNumSortOrder, ptr->DbInfo.wNumSortOrder );
1113                                 }
1114                                 if ( wFlags & FAD_SIZE )
1115                                 {
1116                                         ptr->DbInfo.dwSize = getLong( (rhnd->sock), &size );
1117                                         DBG_printf( "dwSize : %ld (0x%08lx)\n", ptr->DbInfo.dwSize, ptr->DbInfo.dwSize );
1118                                 }
1119                                 if ( wFlags & FAD_LAST_MODIFIED )
1120                                 {
1121                                         getFileTime( (rhnd->sock), &size, &( ptr->DbInfo.ftLastModified ) );
1122                                         DBG_printf( "ftLastModified : %ld (0x%08lx)\n", ptr->DbInfo.ftLastModified, ptr->DbInfo.ftLastModified );
1123                                 }
1124                                 if ( wFlags & FAD_SORT_SPECS )
1125                                 {
1126                                         for ( j = 0; j < CEDB_MAXSORTORDER; j++ )
1127                                         {
1128                                                 getbufferchunk( (rhnd->sock), &size, &( ( ptr->DbInfo.rgSortSpecs ) [ j ] ), sizeof( SORTORDERSPEC ) );
1129                                                 DBG_printf( "sortOrder[%d] : %ld (0x%08lx)\n", j, ( ptr->DbInfo.rgSortSpecs ) [ j ].propid, ( ptr->DbInfo.rgSortSpecs ) [ j ].propid );
1130                                                 DBG_printf( "sortOrder[%d] : %ld (0x%08lx)\n", j, ( ptr->DbInfo.rgSortSpecs ) [ j ].dwFlags, ( ptr->DbInfo.rgSortSpecs ) [ j ].dwFlags );
1131                                         }
1132                                 }
1133                         }
1134                 }
1135         }
1136         return TRUE;
1137 }
1138
1139 STDAPI_( HANDLE ) CeOpenDatabase(RAPIHandleP rhnd, PCEOID poid, LPWSTR lpszName, CEPROPID propid, DWORD dwFlags, HWND hwndNotify )
1140 {
1141         long size = BUFSIZE;
1142         long lng;
1143         HANDLE result;
1144
1145         DBG_printf( "CeOpenDatabase( poid = 0x%08X, lpszName = 0x%08X, propid = 0x%08X, dwFlags = 0x%08X, hwndNotify = 0x%08X )\n",
1146                     poid ? ( (void*)*poid ) : NULL, lpszName, propid, dwFlags, hwndNotify );
1147
1148         initBuf( (rhnd->buffer), size );
1149         pushLong( (rhnd->buffer), size, 0x0E );         /* Command */
1150         pushLong( (rhnd->buffer), size, poid ? ( ( long ) ( *poid ) ) : ( ( long ) NULL ) );            /* Parameter1 : */
1151         pushLong( (rhnd->buffer), size, propid );       /* Parameter2 : */
1152         pushLong( (rhnd->buffer), size, dwFlags );      /* Parameter3 : */
1153         DBG_printbuf( (rhnd->buffer) );
1154         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1155
1156         size = getbufferlen( (rhnd->sock) );
1157         lng = getLong( (rhnd->sock), &size );
1158         DBG_printf( "long 1 (errorcode?): %ld (0x%08lx)\n", lng, lng );
1159         lng = getLong( (rhnd->sock), &size );
1160         DBG_printf( "long 2 (errorcode?): %ld (0x%08lx)\n", lng, lng );
1161         (rhnd->_lasterror) = lng;
1162         result = ( HANDLE ) getLong( (rhnd->sock), &size );
1163         DBG_printf( "long 3 (errorcode?): %ld (0x%08lx)\n", result, result );
1164
1165         return result;
1166 }
1167
1168 STDAPI_( CEOID ) CeReadRecordProps(RAPIHandleP rhnd, HANDLE hDbase, DWORD dwFlags, LPWORD lpcPropID, CEPROPID* rgPropID, LPBYTE* lplpBuffer, LPDWORD lpcbBuffer )
1169 {
1170         long size = BUFSIZE;
1171         long lng;
1172         long index;
1173         long i;
1174         WORD wrd;
1175         CEPROPVAL *ptr;
1176         LPBYTE ptrbyte;
1177         CEOID result;
1178
1179         DBG_printf( "CeReadRecordProps( hDbase = 0x%08X, dwFlags = 0x%08X, lpcPropID = 0x%08X, rgPropID = 0x%08X, lplpBuffer = 0x%08X, lpcbBuffer = 0x%08X )\n",
1180                     hDbase, dwFlags, lpcPropID, rgPropID, lplpBuffer, lpcbBuffer );
1181
1182         initBuf( (rhnd->buffer), size );
1183         pushLong( (rhnd->buffer), size, 0x10 );                 /* Command */
1184         pushLong( (rhnd->buffer), size, ( long ) hDbase );      /* Parameter1 : */
1185         pushLong( (rhnd->buffer), size, dwFlags );              /* Parameter2 : Flags ? */
1186         pushLong( (rhnd->buffer), size, 0 );                    /* Parameter3 */
1187         pushLong( (rhnd->buffer), size, 0 );                    /* Parameter4 */
1188         pushShort( (rhnd->buffer), size, 0 );                   /* Parameter5 */
1189         DBG_printbuf( (rhnd->buffer) );
1190         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1191
1192         size = getbufferlen( (rhnd->sock) );
1193         lng = getLong( (rhnd->sock), &size );
1194         DBG_printf( "long 1 (errorcode?): %ld (0x%08lx)\n", lng, lng );
1195         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
1196         DBG_printf( "long 2: lasterror %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
1197         result = getLong( (rhnd->sock), &size );
1198         DBG_printf( "long 3: CEOID %ld (0x%08lx)\n", result, result );
1199         lng = getLong( (rhnd->sock), &size );
1200         DBG_printf( "long 4: (taille buffer) %ld (0x%08lx)\n", lng, lng );
1201         if ( lpcbBuffer && ( ( *lpcbBuffer ) == 0 ) )
1202         {
1203                 *lpcbBuffer = lng;
1204         }
1205         wrd = getShort( (rhnd->sock), &size );
1206         DBG_printf( "word 1: (nbprops) %ld (0x%08lx)\n", wrd, wrd );
1207         if ( !rgPropID )
1208         {
1209                 if ( lpcPropID )
1210                 {
1211                         *lpcPropID = wrd;
1212                 }
1213         }
1214
1215         /*      if( cFindData )
1216                 {
1217                         *cFindData = wrd;
1218                 }*/
1219         if ( lplpBuffer && ( wrd > 0 ) )
1220         {
1221                 if ( *lplpBuffer == NULL )
1222                 {
1223                         DBG_printf( "Before allocation\n" );
1224                         *lplpBuffer = ( LPBYTE ) calloc( 1, lng );
1225                         DBG_printf( "After allocation : *ppFindData = %08X\n", *lplpBuffer );
1226                 }
1227                 ptr = ( CEPROPVAL * ) ( *lplpBuffer );
1228                 for ( i = 0; i < wrd; i++ )
1229                 {
1230                         DBG_printf( "i=%d : ptr=%08X\n", i, ptr );
1231                         getbufferchunk( (rhnd->sock), &size, &( ptr[ i ] ), sizeof( CEPROPVAL ) );
1232                         DBG_printf( "propval: propid %ld (0x%08lx) \n", ptr[ i ].propid, ptr[ i ].propid );
1233                         DBG_printf( "propval: wLenData %d (0x%04x) \n", ptr[ i ].wLenData, ptr[ i ].wLenData );
1234                         DBG_printf( "propval: wFlags %d (0x%04x) \n", ptr[ i ].wFlags, ptr[ i ].wFlags );
1235                         switch ( ( ptr[ i ].propid ) & 0xFFFF )
1236                         {
1237                                 case CEVT_BLOB:
1238                                         ptr[ i ].val.blob.lpb = ( LPBYTE ) ( ( DWORD ) ptr + ( DWORD ) ptr[ i ].val.blob.lpb );
1239                                         DBG_printf( "propval: BLOB (size : %d, ptr %-8X)\n", ptr[ i ].val.blob.dwCount, ptr[ i ].val.blob.lpb );
1240                                         break;
1241                                 case CEVT_LPWSTR:
1242                                         ptr[ i ].val.lpwstr = ( LPWSTR ) ( ( DWORD ) ptr + ( DWORD ) ptr[ i ].val.lpwstr );
1243                                         DBG_printf( "propval: LPWSTR %ld (0x%08lx) \n", ptr[ i ].val.lpwstr, ptr[ i ].val.lpwstr );
1244                                         break;
1245                                 case CEVT_I2:
1246                                         DBG_printf( "propval: I2 %d (0x%04x) \n", ptr[ i ].val.iVal, ptr[ i ].val.iVal );
1247                                         break;
1248                                 case CEVT_UI2:
1249                                         DBG_printf( "propval: UI2 %d (0x%04x) \n", ptr[ i ].val.uiVal, ptr[ i ].val.uiVal );
1250                                         break;
1251                                 case CEVT_I4:
1252                                         DBG_printf( "propval: I4 %ld (0x%08lx) \n", ptr[ i ].val.lVal, ptr[ i ].val.lVal );
1253                                         break;
1254                                 case CEVT_UI4:
1255                                         DBG_printf( "propval: UI4 %ld (0x%08lx) \n", ptr[ i ].val.ulVal, ptr[ i ].val.ulVal );
1256                                         break;
1257                                 case CEVT_BOOL:
1258                                         DBG_printf( "propval: BOOL %s\n", ptr[ i ].val.boolVal ? "true" : "false" );
1259                                         break;
1260                                 case CEVT_FILETIME:
1261                                         DBG_printf( "propval: FILETIME 0x%-8x\n", ptr[ i ].val.filetime );
1262                                         break;
1263                                 case CEVT_R8:
1264                                         DBG_printf( "propval: R8 %d ", ptr[ i ].val.dblVal );
1265                                         break;
1266                                 default:
1267                                         break;
1268                         }
1269                         /*                      DBG_printf( "propval: sz:%d %ld (0x%08lx) \n", sizeof(CEVALUNION), valunion, valunion ); */
1270                 }
1271
1272                 ptrbyte = ( LPBYTE ) & ( ptr[ wrd ] );
1273                 index = ( long ) ( lng - ( ptrbyte - ( *lplpBuffer ) ) );
1274                 DBG_printf( " getchunk : index = %d, size = %d\n", index, size );
1275                 getbufferchunk( (rhnd->sock), &size, ptrbyte, ( ( long ) ptrbyte > index ) ? index : ( long ) ptrbyte );
1276         }
1277         return result;
1278 }
1279
1280 STDAPI_(CEOID) CeWriteRecordProps(RAPIHandleP rhnd, HANDLE hDbase, CEOID oidRecord, WORD cPropID, CEPROPVAL* rgPropVal)
1281 {
1282         long size = BUFSIZE;
1283         long lng;
1284         long datalen, buflen;
1285         long i;
1286         CEOID result;
1287
1288         DBG_printf( "CeWriteRecordProps( hDbase = 0x%08X, oidRecord = 0x%08X, cPropID = 0x%08X, rgPropVal = 0x%08X )\n",
1289                     hDbase, oidRecord, cPropID, rgPropVal );
1290
1291         /*
1292         *       Format of the CeWriteRecordProps packet - primitives are encoded in the CEPROPVAL structures, lpwstr and blob properties are
1293         *       attached to the end of the buffer and referenced by offset pointers
1294         *
1295         *               long hDBase | long oidRecord | long cPropID | long datalen (of following data) | n * CEPROPVAL | char[] data
1296         *
1297         *       Because CEPROPVAL is a union, the format is different for every type of prop:
1298         *
1299         *       long or short (iVal, uiVal, lVal, ulVal, boolVal): long propid | short wFlags | short wLenData (unused, set to 0) | short iVal or boolVal | short uiVal | long lVal or ulVal
1300         *
1301         *       FILETIME or double: long propid | short wFlags | short wLenData (unused) | DWORD FILETIME or double
1302         *
1303         *       lpwstr: long propid | short wFlags | short wLenData (unused) | long offset ( points to string data in data buffer, counted from beginning of CEPROPVALs)
1304         *
1305         *       blob: long propid | short wFlags | short wLenData (unused) | long blobsize | long offset (same as lpwstr)
1306         */
1307         
1308         
1309         initBuf( (rhnd->buffer), size );
1310         pushLong( (rhnd->buffer), size, 0x11 );                 /* Command */
1311         pushLong( (rhnd->buffer), size, ( long ) hDbase );      /* Parameter1 : */
1312         pushLong( (rhnd->buffer), size, oidRecord );            /* Parameter2 : Flags ? */
1313         pushShort( (rhnd->buffer), size, cPropID );                     /* Parameter3 */
1314
1315
1316 /*
1317         * we have to go through the rgPropVals array three times:
1318         *               1. to determine the size of the whole buffer, including data
1319         *               2. to write out the CEPROPVAL array
1320         *               3. to write the data segment
1321         */
1322                 
1323         /* calculate the length of the whole buffer, including the data segment at the end */
1324         
1325         buflen = cPropID * sizeof( CEPROPVAL ); /* length of all cepropvals */
1326         
1327         for ( i = 0; i < cPropID; i++ )
1328         {       
1329                 switch ( ( rgPropVal[i].propid ) & 0xFFFF )
1330                 {
1331                         case CEVT_BLOB:
1332                                         buflen += rgPropVal[i].val.blob.dwCount;
1333                                 break;
1334                         case CEVT_LPWSTR:
1335                                         buflen += 2* ( wcslen( rgPropVal[i].val.lpwstr ) + 1 );
1336                                 break;
1337                         default:
1338                                 break;
1339                 }
1340         }
1341         
1342         pushLong( (rhnd->buffer), size, buflen);                                
1343         
1344         /*
1345          second time: write n * CEPROPVAL. Can't do it in one block, as we have to adjust the buffer offsets
1346          */
1347         
1348         datalen = cPropID * sizeof( CEPROPVAL ); /*  holds the offset to the end of the data buffer     */
1349         
1350         for ( i = 0; i < cPropID; i++ )
1351         {
1352                 pushLong( (rhnd->buffer), size,  rgPropVal[i].propid );
1353                 pushShort( (rhnd->buffer), size,  rgPropVal[i].wLenData );
1354                 pushShort( (rhnd->buffer), size,  rgPropVal[i].wFlags );
1355                 
1356                 switch ( ( rgPropVal[i].propid ) & 0xFFFF )
1357                 {
1358                         case CEVT_BLOB:
1359                                         pushLong( (rhnd->buffer), size, rgPropVal[i].val.blob.dwCount );
1360                                         datalen += rgPropVal[i].val.blob.dwCount;
1361                                         pushLong( (rhnd->buffer), size, datalen );                      
1362                                 break;
1363                         case CEVT_LPWSTR:
1364                                         datalen += 2* ( wcslen( rgPropVal[i].val.lpwstr ) + 1 );
1365                                         pushLong( (rhnd->buffer), size, datalen );
1366                                         pushLong( (rhnd->buffer), size, 0 );                    
1367                                 break;
1368                         case CEVT_I2:
1369                         case CEVT_UI2:
1370                         case CEVT_I4:
1371                         case CEVT_UI4:
1372                                 pushShort( (rhnd->buffer), size, rgPropVal[i].val.iVal );
1373                                 pushShort( (rhnd->buffer), size, rgPropVal[i].val.uiVal );
1374                                 pushLong( (rhnd->buffer), size, rgPropVal[i].val.lVal );
1375                                 break;
1376                         case CEVT_BOOL:
1377                                 pushShort( (rhnd->buffer), size, rgPropVal[i].val.boolVal  );
1378                                 pushShort( (rhnd->buffer), size, 0 );
1379                                 pushLong( (rhnd->buffer), size, 0 );
1380                                 break;
1381                         case CEVT_FILETIME:
1382                                 /* this assumes that the FILETIME is already in ole32 format! Is this a problem? */
1383                                 pushLong( (rhnd->buffer), size, rgPropVal[i].val.filetime.dwLowDateTime );
1384                                 pushLong( (rhnd->buffer), size, rgPropVal[i].val.filetime.dwHighDateTime );
1385                                 break;
1386                         case CEVT_R8:
1387                                 pushParameter(rhnd, size, &(rgPropVal[i].val.dblVal), 4, 1 );
1388                                 break;
1389                         default:
1390                                 break;
1391                 }
1392         }       
1393         
1394         /* 3. write the data segment */
1395         
1396         for ( i = 0; i < cPropID; i++ )
1397         {       
1398                 switch ( ( rgPropVal[i].propid ) & 0xFFFF )
1399                 {
1400                         case CEVT_BLOB:
1401                                         pushParameter_no_size(rhnd, size, rgPropVal[i].val.blob.lpb, rgPropVal[i].val.blob.dwCount );                                   
1402                                 break;
1403                         case CEVT_LPWSTR:
1404                                         pushParameter_no_size(rhnd, size, rgPropVal[i].val.lpwstr, 2* ( wcslen( rgPropVal[i].val.lpwstr ) + 1) );
1405                                 break;
1406                         default:
1407                                 break;
1408                 }
1409         }       
1410         
1411         DBG_printbuf( (rhnd->buffer) );
1412         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1413
1414         size = getbufferlen( (rhnd->sock) );
1415
1416         lng = getLong( (rhnd->sock), &size );
1417         DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
1418         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
1419         DBG_printf( "long 2 (errorcode?): %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
1420         result = ( HANDLE ) getLong( (rhnd->sock), &size );
1421         DBG_printf( "long 3 (HANDLE): %ld (0x%08lx)\n", result, result );
1422
1423         if ( size > 0 )
1424         {
1425                 flushbuffer( (rhnd->sock) );
1426         }
1427
1428         return result;
1429 }
1430
1431
1432 /* ================================================================================================================= */
1433 /* ================================================================================================================= */
1434 /*  RAPI - Processes */
1435 /* ================================================================================================================= */
1436 /* ================================================================================================================= */
1437
1438 STDAPI_( BOOL ) CeCreateProcess(RAPIHandleP rhnd, LPCWSTR lpApplicationName,
1439                                  LPCWSTR lpCommandLine, 
1440                                  LPSECURITY_ATTRIBUTES lpProcessAttributes,
1441                                  LPSECURITY_ATTRIBUTES lpThreadAttributes,
1442                                  BOOL bInheritHandles, 
1443                                  DWORD dwCreationFlags,
1444                                  LPVOID lpEnvironment, 
1445                                  LPWSTR lpCurrentDirectory, 
1446                                  LPSTARTUPINFO lpStartupInfo,
1447                                  LPPROCESS_INFORMATION lpProcessInformation )
1448 {
1449         long size = BUFSIZE;
1450         long lng;
1451         long stlen;
1452         BOOL result = FALSE;
1453
1454         DBG_printf( "CeCreateProcess( lpApplication = 0x%08X, lpCommandLine = 0x%08X )\n",
1455                     lpApplicationName, lpCommandLine );
1456
1457         initBuf( (rhnd->buffer), size );
1458         pushLong( (rhnd->buffer), size, 0x19 );         /* Command */
1459         if(lpApplicationName!=NULL)
1460         {
1461                 pushLong( (rhnd->buffer), size, 0x01 );
1462                 stlen = wcslen( lpApplicationName );
1463                 pushLong( (rhnd->buffer), size, (stlen+1)*2 );
1464                 pushLong( (rhnd->buffer), size, 0x01 );
1465                 pushString( (rhnd->buffer), size, lpApplicationName );
1466         }
1467         else
1468         {
1469                 pushLong( (rhnd->buffer), size, 0x00 );
1470         }
1471         if(lpCommandLine!=NULL)
1472         {
1473                 pushLong( (rhnd->buffer), size, 0x01 );
1474                 stlen = wcslen( lpCommandLine );
1475                 pushLong( (rhnd->buffer), size, (stlen+1)*2 );
1476                 pushLong( (rhnd->buffer), size, 0x01 );
1477                 pushString( (rhnd->buffer), size, lpCommandLine );
1478         }
1479         else
1480         {
1481                 pushLong( (rhnd->buffer), size, 0x00 );
1482         }
1483         
1484         pushLong( (rhnd->buffer), size, 0x00 ); /* Parameter3 : lpProcessAttibutes ? */
1485         pushLong( (rhnd->buffer), size, 0x00 ); /* Parameter4 : lpThreadAttributes ? */
1486         pushLong( (rhnd->buffer), size, 0x00 ); /* Parameter5 : bInheritHandles ? */
1487         pushLong( (rhnd->buffer), size, dwCreationFlags ); 
1488         pushLong( (rhnd->buffer), size, 0x00 ); /* Parameter7 : lpEnvironment ? */
1489         pushLong( (rhnd->buffer), size, 0x00 ); /* Parameter8 : lpCurrentDirectory ? */
1490         pushLong( (rhnd->buffer), size, 0x00 ); /* Parameter9 : lpStartupInfo ? */
1491         pushLong( (rhnd->buffer), size, 0x00 ); /* Parametera : lpProcessInformation ? */
1492
1493         DBG_printbuf( (rhnd->buffer) );
1494
1495         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1496
1497         size = getbufferlen( (rhnd->sock) );
1498         lng = getLong( (rhnd->sock), &size );
1499         DBG_printf( "long 1 (errorcode?): %ld (0x%08lx)\n", lng, lng );
1500         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
1501         DBG_printf( "long 2: lasterror %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
1502
1503         result = getLong( (rhnd->sock), &size );
1504         DBG_printf( "long 3: %ld (0x%08lx)\n", result, result );
1505         if(result)
1506         {
1507                 lng = getLong( (rhnd->sock), &size );
1508                 DBG_printf( "long 4: %ld (0x%08lx)\n", lng, lng );
1509                 lng = getLong( (rhnd->sock), &size );
1510                 DBG_printf( "long 5: %ld (0x%08lx)\n", lng, lng );
1511                 lng = getLong( (rhnd->sock), &size );
1512                 DBG_printf( "long 6: %ld (0x%08lx)\n", lng, lng );
1513                 lng = getLong( (rhnd->sock), &size );
1514                 DBG_printf( "long 7: %ld (0x%08lx)\n", lng, lng );
1515                 lng = getLong( (rhnd->sock), &size );
1516                 DBG_printf( "long 8: %ld (0x%08lx)\n", lng, lng );
1517                 lng = getLong( (rhnd->sock), &size );
1518                 DBG_printf( "long 9: %ld (0x%08lx)\n", lng, lng );
1519                 lng = getLong( (rhnd->sock), &size );
1520                 DBG_printf( "long a: %ld (0x%08lx)\n", lng, lng );
1521         }
1522         else
1523         {
1524                 lng = getLong( (rhnd->sock), &size );
1525                 DBG_printf( "long 4: %ld (0x%08lx)\n", lng, lng );
1526         }
1527
1528         if ( size > 0 )
1529         {
1530                 flushbuffer( (rhnd->sock) );
1531         }
1532
1533         return result;
1534 }
1535
1536 /* ================================================================================================================= */
1537 /* ================================================================================================================= */
1538 /*  RAPI - General */
1539 /* ================================================================================================================= */
1540 /* ================================================================================================================= */
1541
1542 STDAPI_( BOOL ) CeCloseHandle(RAPIHandleP rhnd, HANDLE hObject )
1543 {
1544         long size = BUFSIZE;
1545         long lng;
1546
1547         DBG_printf( "CeCloseHandle()\n" );
1548
1549         initBuf( (rhnd->buffer), size );
1550         pushLong( (rhnd->buffer), size, 0x08 );                 /* Command */
1551         pushLong( (rhnd->buffer), size, ( long ) hObject );     /* Parameter1 : */
1552         DBG_printbuf( (rhnd->buffer) );
1553         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1554
1555         size = getbufferlen( (rhnd->sock) );
1556         lng = getLong( (rhnd->sock), &size );
1557         DBG_printf( "long 1 : %ld (0x%08lx)\n", lng, lng );
1558         (rhnd->_lasterror) = getLong( (rhnd->sock), &size );
1559         DBG_printf( "long 2 (lasterror): %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror) );
1560         lng = getLong( (rhnd->sock), &size );
1561         DBG_printf( "long 3 : %ld (0x%08lx)\n", lng, lng );
1562
1563         return lng;
1564 }
1565
1566 STDAPI_( DWORD ) CeGetLastError(RAPIHandleP rhnd)
1567 {
1568         return (rhnd->_lasterror);
1569 }
1570
1571 /* ================================================================================================================= */
1572 /* ================================================================================================================= */
1573 /*  RAPI - Library */
1574 /* ================================================================================================================= */
1575 /* ================================================================================================================= */
1576
1577 void findquotes( char * *ptrstart, char * *ptrstop )
1578 {
1579         /* Go to the first double quote */
1580         /* ---------------------------- */
1581         while( ( *(*ptrstart) != 0 ) && ( *(*ptrstart) != '"' ) )
1582         {
1583                 (*ptrstart) ++;
1584         }
1585         if( *(*ptrstart) != 0 )
1586         {
1587                 (*ptrstart) ++;
1588                 *ptrstop = *ptrstart;
1589                 /* Reach the next double quote */
1590                 /* --------------------------- */
1591                 while( ( *(*ptrstop) != 0 ) && ( *(*ptrstop) != '"' ) )
1592                 {
1593                         (*ptrstop) ++;
1594                 }
1595         }
1596 }
1597
1598 int parseinfofile( RAPIHandleP rhnd );
1599
1600 int parseinfofile( RAPIHandleP rhnd )
1601 {
1602         BOOL result = FALSE;
1603         struct stat st;
1604         int res;
1605         FILE * f;
1606         char line[ 1024 ];
1607         char * ptrstart;
1608         char * ptrstop;
1609         BOOL devicefound;
1610         int i;
1611
1612         devicefound = FALSE;
1613
1614         DBG_printf( "Before stat...\n" );
1615         res = stat( INFOFILE, &st );
1616         DBG_printf( "stat(), result = %d...\n", res );
1617         if ( res != -1 )
1618         {
1619                 f = fopen( INFOFILE, "r" );
1620                 DBG_printf( "fopen(), result = 0x%08X...\n", f );
1621                 if ( f )
1622                 {
1623                         while ( ( !feof( f ) ) && ( result == FALSE ) )
1624                         {
1625                                 line[ 0 ] = '\0';
1626                                 if ( fgets( line, 1024, f ) != NULL )
1627                                 {
1628                                         DBG_printf( "fscanf(), line = '%s'...\n", line );
1629                                         if ( line[ 0 ] != '#' )
1630                                         {
1631                                                 /* Beginning of block : device <IP> { */
1632                                                 /* ---------------------------------- */
1633                                                 if( ((rhnd->hostname)==NULL) && ( ( ptrstart = strstr( line, "device" ) ) != NULL ) )
1634                                                 {       
1635                                                         devicefound = TRUE;
1636                                                         ptrstart += 7;
1637                                                         for ( ptrstop = ptrstart; ( ( *ptrstop ) != 0 ) && ( ( *ptrstop ) != '{' ); ptrstop++ );
1638                                                         ( *ptrstop ) = 0;
1639                                                         (rhnd->hostname) = strdup( ptrstart );
1640                                                         DBG_printf( "strdup(), hostname = '%s'...\n", (rhnd->hostname) );
1641                                                 }
1642
1643                                                 if( devicefound )
1644                                                 {
1645
1646                                                         /* End of block : } */
1647                                                         /* ---------------- */
1648                                                         if( strstr( line, "}" ) != NULL )
1649                                                         {
1650
1651                                                                 devicefound = FALSE;
1652                                                                 result = TRUE;
1653
1654                                                         } else {
1655
1656                                                                 /* let's check for the passphrase */
1657                                                                 /* ------------------------------ */
1658                                                                 if( ( ((rhnd->lockbuffersize)!=0) || ((rhnd->lockbuffer)==NULL)) && ( ( ptrstart = strstr( line, "passphrase" ) ) != NULL ) )
1659                                                                 {
1660                                                                         DBG_printf( "found string passphrase = %s\n", line );
1661                                                                         findquotes( &ptrstart, &ptrstop );
1662
1663                                                                         if( (*ptrstart) != 0 )
1664                                                                         {
1665                                                                                 (*ptrstop) = '\0';
1666                                                                                 if( NULL != strstr( line, "size" ) )
1667                                                                                 {
1668                                                                                         DBG_printf( "found string passphrase-size = %s\n", ptrstart );
1669                                                                                         if( 1 == sscanf( ptrstart, "%d", &(rhnd->lockbuffersize) ) )
1670                                                                                         {
1671                                                                                                 DBG_printf( "found passphrase-size = %d\n", (rhnd->lockbuffersize) );
1672                                                                                                 (rhnd->lockbuffer) = (unsigned char *) malloc( 1+ (rhnd->lockbuffersize) );
1673                                                                                         }
1674                                                                                 } else {
1675                                                                                         for( i=0; i<(rhnd->lockbuffersize); i++ )
1676                                                                                         {
1677                                                                                                 sscanf( ptrstart + (3*i), "%02X", (unsigned int *)&((rhnd->lockbuffer)[i]) );
1678                                                                                                 DBG_printf("%02X ", (rhnd->lockbuffer)[i] );
1679                                                                                         }
1680                                                                                         DBG_printf( "\nfound passphrase-data = %s\n", ptrstart );
1681                                                                                 }
1682                                                                         }
1683                                                                 }
1684                                                         }
1685                                                 }
1686                                         }
1687                                 }
1688                         }
1689                         fclose( f );
1690                 }
1691         }
1692         return result;
1693 }
1694
1695 STDAPI_( HRESULT ) CeRapiInit(RAPIHandleP rhnd)
1696 {
1697         if ( (rhnd->sock) == 0 )
1698         {
1699                 parseinfofile(rhnd);
1700                 if ( (rhnd->hostname) )
1701                 {
1702                         DBG_printf( "CeRapiInit(%s)\n", (rhnd->hostname) );
1703                         (rhnd->sock) = SockOpen( (rhnd->hostname), 990 );
1704                         if ( (rhnd->sock) > 0 )
1705                         {
1706                                 DBG_printf( "CeRapiInit(%s) ok\n", (rhnd->hostname) );
1707                                 free( (rhnd->hostname) );
1708                                 (rhnd->buffer) = (rapibuffer *)malloc( 4 + BUFSIZE );
1709
1710         checkpassword(rhnd);
1711
1712                                 return E_SUCCESS;
1713                         }
1714                         else
1715                         {
1716                                 DBG_printf( "CeRapiInit(%s) Nok\n", (rhnd->hostname) );
1717                                 free( (rhnd->hostname) );
1718                                 return E_FAIL;
1719                         }
1720                         free( (rhnd->hostname) );
1721                 }
1722                 else
1723                 {
1724                         DBG_printf( "No CE Device found !?!\n" );
1725                         return E_FAIL;
1726                 }
1727         }
1728         else
1729         {
1730                 DBG_printf( "CeRapiInit() already done\n" );
1731                 return CERAPI_E_ALREADYINITIALIZED;
1732         }
1733 }
1734 /* STDAPI CeRapiInitEx (RAPIINIT*); */
1735
1736 STDAPI_( HRESULT ) CeRapiUninit(RAPIHandleP rhnd)
1737 {
1738         HRESULT result = FALSE;
1739         if( (rhnd->buffer) )
1740         {
1741                 free( (rhnd->buffer) );
1742                 (rhnd->buffer) = NULL;
1743         }
1744         if ( (rhnd->sock) > 0 )
1745         {
1746                 result = (close( (rhnd->sock) )==0) ? TRUE : FALSE;
1747                 DBG_printf( "CeRapiUninit() %s\n", (result ? "ok" : "failed") );
1748                 
1749                 /* the following is needed to make subsequent init/uninit calls to RAPI
1750                  * (e.g. device disconnect/reconnect) */
1751         
1752                 if (result) {
1753                         (rhnd->sock) = 0;
1754                         (rhnd->hostname) = NULL;
1755                 }
1756                         
1757         }
1758         else
1759         {
1760                 DBG_printf( "CeRapiUninit() no need\n" );
1761         }
1762         return result;
1763 }
1764
1765 STDAPI_( HRESULT ) CeRapiFreeBuffer(RAPIHandleP rhnd, LPVOID Buffer )
1766 {
1767         if ( Buffer )
1768         {
1769                 free( Buffer );
1770         }
1771         return ( HRESULT ) NULL;
1772 }
1773
1774 STDAPI_(BOOL) CeGetVersionEx(RAPIHandleP rhnd,LPCEOSVERSIONINFO lpVersion)
1775 {
1776         BOOL result = FALSE;
1777         long size = BUFSIZE;
1778         LONG lng;
1779
1780 //      checkpassword();
1781         
1782         initBuf((rhnd->buffer), size);
1783         
1784         pushLong((rhnd->buffer), size, 0x3B);   /* Command */
1785         pushParameter(rhnd,size, lpVersion, lpVersion->dwOSVersionInfoSize, 0);
1786         
1787         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1788         size = getbufferlen( (rhnd->sock) );
1789
1790         /*
1791          * The return package looks like this
1792          *
1793          * Offset  Size  Value
1794          * 00      4     0
1795          * 04      4     0
1796          * 08      4     1
1797          * 0c      4     n = real size of buffer
1798          * 10      n     first n bytes of struct
1799          */
1800         
1801         lng = getLong((rhnd->sock), &size); 
1802         (rhnd->_lasterror) = getLong((rhnd->sock), &size);
1803
1804         if (0 == lng)
1805         {
1806                 result = getLong((rhnd->sock), &size);
1807                 if (1 == result)
1808                 {
1809                         long real_length = getLong((rhnd->sock), &size);
1810                         getbufferchunk((rhnd->sock), &size, lpVersion, real_length);
1811                 }
1812         }
1813         else
1814         {
1815                 DBG_printf("Warning: expected 0 but got %i=0x%x\n", lng, lng);
1816         }
1817         
1818         if ( size > 0 )
1819         {
1820                 DBG_printf( "size : %d\n", size );
1821                 flushbuffer( (rhnd->sock) );
1822         }       
1823         
1824         return result;
1825 }
1826
1827 STDAPI_(BOOL) CeCreateDirectory(RAPIHandleP rhnd,LPCWSTR lpDirName, LPSECURITY_ATTRIBUTES lpSecAttr)
1828 {
1829         BOOL result = FALSE;
1830         long size = BUFSIZE;
1831         LONG lng;
1832         
1833         initBuf((rhnd->buffer), size);
1834         
1835         pushLong((rhnd->buffer), size, 0x17);   /* Command */
1836         pushParameter(rhnd,size, (void*)lpDirName, (wcslen(lpDirName) + 1) * sizeof(WCHAR), 1);
1837         pushLong((rhnd->buffer), size, 0);      /* lpSecAttr not used */
1838         
1839         /*DBG_printbuf( (rhnd->buffer) );*/
1840         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1841         size = getbufferlen( (rhnd->sock) );
1842
1843         /*
1844          * The return package looks like this
1845          *
1846          * Offset  Size  Value
1847          * 00      4     0
1848          * 04      4     error code if the value below is 0
1849          * 08      4     0/1
1850         */
1851
1852         lng = getLong((rhnd->sock), &size); 
1853         (rhnd->_lasterror) = getLong((rhnd->sock), &size);
1854
1855         if (0 == lng)
1856         {
1857                 result = getLong((rhnd->sock), &size);
1858         }
1859         else
1860         {
1861                 DBG_printf("Warning: expected 0 but got %i=0x%x\n", lng, lng);
1862         }
1863         
1864         if ( size > 0 )
1865         {
1866                 DBG_printf( "size : %d\n", size );
1867                 flushbuffer( (rhnd->sock) );
1868         }       
1869         
1870         return result;
1871 }
1872
1873 STDAPI_(BOOL) CeRemoveDirectory(RAPIHandleP rhnd,LPCWSTR lpPathName)
1874 {
1875         BOOL result = FALSE;
1876         long size = BUFSIZE;
1877         LONG lng;
1878         
1879         initBuf((rhnd->buffer), size);
1880         
1881         pushLong((rhnd->buffer), size, 0x18);   /* Command */
1882         pushParameter(rhnd,size, (void*)lpPathName, (wcslen(lpPathName) + 1) * sizeof(WCHAR), 1);
1883         
1884         /*DBG_printbuf( (rhnd->buffer) );*/
1885         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1886         size = getbufferlen( (rhnd->sock) );
1887
1888         /*
1889          * The return package looks like this
1890          *
1891          * Offset  Size  Value
1892          * 00      4     0
1893          * 04      4     error code if the value below is 0
1894          * 08      4     0/1
1895         */
1896
1897         lng = getLong((rhnd->sock), &size); 
1898         (rhnd->_lasterror) = getLong((rhnd->sock), &size);
1899
1900         if (0 == lng)
1901         {
1902                 result = getLong((rhnd->sock), &size);
1903         }
1904         else
1905         {
1906                 DBG_printf("Warning: expected 0 but got %i=0x%x\n", lng, lng);
1907         }
1908         
1909         if ( size > 0 )
1910         {
1911                 DBG_printf( "size : %d\n", size );
1912                 flushbuffer( (rhnd->sock) );
1913         }       
1914         
1915         return result;
1916 }
1917
1918 STDAPI_(BOOL) CeDeleteFile(RAPIHandleP rhnd,LPCWSTR lpFileName)
1919 {
1920         BOOL result = FALSE;
1921         long size = BUFSIZE;
1922         LONG lng;
1923         
1924         initBuf((rhnd->buffer), size);
1925         
1926         pushLong((rhnd->buffer), size, 0x1c);   /* Command */
1927         pushParameter(rhnd,size, (void*)lpFileName, (wcslen(lpFileName) + 1) * sizeof(WCHAR), 1);
1928         
1929         /*DBG_printbuf( (rhnd->buffer) );*/
1930         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1931         size = getbufferlen( (rhnd->sock) );
1932
1933         /*
1934          * The return package looks like this
1935          *
1936          * Offset  Size  Value
1937          * 00      4     0
1938          * 04      4     error code if the value below is 0
1939          * 08      4     0/1
1940         */
1941
1942         lng = getLong((rhnd->sock), &size); 
1943         DBG_printf("long 1 : %ld (0x%08lx)\n", lng, lng);
1944         (rhnd->_lasterror) = getLong((rhnd->sock), &size);
1945         DBG_printf("long 2 : %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror));
1946
1947         if (0 == lng)
1948         {
1949                 result = getLong((rhnd->sock), &size);
1950                 DBG_printf("long 3 : %ld (0x%08lx)\n", result, result);
1951         }
1952         else
1953         {
1954                 DBG_printf("Warning: expected 0 but got %i=0x%x\n", lng, lng);
1955         }
1956         
1957         if ( size > 0 )
1958         {
1959                 DBG_printf( "size : %d\n", size );
1960                 flushbuffer( (rhnd->sock) );
1961         }       
1962         
1963         return result;
1964 }
1965
1966 STDAPI_( BOOL ) CeMoveFile(RAPIHandleP rhnd, LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName )
1967 {
1968         BOOL result = FALSE;
1969         long size = BUFSIZE;
1970         LONG lng;
1971         
1972         initBuf((rhnd->buffer), size);
1973         
1974         pushLong((rhnd->buffer), size, 0x1a);   /* Command */
1975         pushParameter(rhnd,size, (void*)lpExistingFileName, (wcslen(lpExistingFileName) + 1) * sizeof(WCHAR), 1);
1976         pushParameter(rhnd,size, (void*)lpNewFileName, (wcslen(lpNewFileName) + 1) * sizeof(WCHAR), 1);
1977         
1978         /*DBG_printbuf( (rhnd->buffer) );*/
1979         sendbuffer( (rhnd->sock), (rhnd->buffer) );
1980         size = getbufferlen( (rhnd->sock) );
1981
1982         /*
1983          * The return package looks like this
1984          *
1985          * Offset  Size  Value
1986          * 00      4     0
1987          * 04      4     error code if the value below is 0
1988          * 08      4     0/1
1989         */
1990
1991         lng = getLong((rhnd->sock), &size); 
1992         DBG_printf("long 1 : %ld (0x%08lx)\n", lng, lng);
1993         (rhnd->_lasterror) = getLong((rhnd->sock), &size);
1994         DBG_printf("long 2 : %ld (0x%08lx)\n", (rhnd->_lasterror), (rhnd->_lasterror));
1995
1996         if (0 == lng)
1997         {
1998                 result = getLong((rhnd->sock), &size);
1999                 DBG_printf("long 3 : %ld (0x%08lx)\n", result, result);
2000         }
2001         else
2002         {
2003                 DBG_printf("Warning: expected 0 but got %i=0x%x\n", lng, lng);
2004         }
2005         
2006         if ( size > 0 )
2007         {
2008                 DBG_printf( "size : %d\n", size );
2009                 flushbuffer( (rhnd->sock) );
2010         }       
2011         
2012         return result;
2013 }
2014
2015 void CeGetSystemInfo(RAPIHandleP rhnd,LPSYSTEM_INFO lpSystemInfo)
2016 {
2017         BOOL result = FALSE;
2018         long size = BUFSIZE;
2019         LONG lng;
2020         
2021         initBuf((rhnd->buffer), size);
2022         
2023         pushLong((rhnd->buffer), size, 0x2f);   /* Command */
2024         pushParameter(rhnd,size, lpSystemInfo, sizeof(SYSTEM_INFO), 0);
2025         
2026         sendbuffer( (rhnd->sock), (rhnd->buffer) );
2027         size = getbufferlen( (rhnd->sock) );
2028
2029         /*
2030          * The return package looks like this
2031          *
2032          * Offset  Size  Value
2033          * 00      4     0
2034          * 04      4     0
2035          * 08      4     1
2036          * 0c      4     n = real size of buffer
2037          * 10      n     first n bytes of struct
2038          */
2039         
2040         lng = getLong((rhnd->sock), &size); 
2041         (rhnd->_lasterror) = getLong((rhnd->sock), &size);
2042
2043         /*
2044          * Note: On my system, 36 bytes are returned but sizeof(SYSTEM_INFO) is only 32!
2045          *
2046          * "Overflow by 4 bytes. Parameter size is 36 bytes but max 32 bytes was expected."
2047          */
2048         
2049         if (0 == lng)
2050         {
2051                 popParameter(rhnd,&size, lpSystemInfo, sizeof(SYSTEM_INFO));
2052         }
2053         else
2054         {
2055                 DBG_printf("Warning: expected 0 but got %i=0x%x\n", lng, lng);
2056         }
2057         
2058         if ( size > 0 )
2059         {
2060                 DBG_printf( "size : %d\n", size );
2061                 flushbuffer( (rhnd->sock) );
2062         }       
2063 }
2064
2065