Windows: Suspend/Resume for afsd_service
[openafs.git] / src / WINNT / afsrdr / user / RDRInit.cpp
1 /*
2  * Copyright (c) 2008 Secure Endpoints, Inc.
3  * Copyright (c) 2009-2011 Your File System, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * - Redistributions of source code must retain the above copyright notice,
10  *   this list of conditions and the following disclaimer.
11  * - Redistributions in binary form must reproduce the above copyright notice,
12  *   this list of conditions and the following disclaimer in the documentation
13  *   and/or other materials provided with the distribution.
14  * - Neither the name of Secure Endpoints Inc. nor the names of its contributors
15  *   may be used to endorse or promote products derived from this software without
16  *   specific prior written permission from Secure Endpoints, Inc. and
17  *   Your File System, Inc.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
23  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #ifndef _WIN32_WINNT
33 #define _WIN32_WINNT 0x0500
34 #endif
35 #define _CRT_SECURE_NO_DEPRECATE
36 #define _CRT_NON_CONFORMING_SWPRINTFS
37 #define UNICODE 1
38 #define STRSAFE_NO_DEPRECATE
39
40 #include <ntstatus.h>
41 #define WIN32_NO_STATUS
42 #include <windows.h>
43 typedef LONG NTSTATUS, *PNTSTATUS;      // not declared in ntstatus.h
44
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <stdarg.h>
48 #include <errno.h>
49
50 #include <devioctl.h>
51
52 #include <tchar.h>
53 #include <winbase.h>
54 #include <winreg.h>
55 #include <strsafe.h>
56
57 #include "..\\Common\\AFSUserDefines.h"
58 #include "..\\Common\\AFSUserIoctl.h"
59 #include "..\\Common\\AFSUserStructs.h"
60
61 extern "C" {
62 #include <osilog.h>
63 extern osi_log_t *afsd_logp;
64
65 #include <WINNT/afsreg.h>
66 #include <afs/cm_config.h>
67 #include <afs/cm_error.h>
68 }
69 #include <RDRPrototypes.h>
70
71 #ifndef FlagOn
72 #define FlagOn(_F,_SF)        ((_F) & (_SF))
73 #endif
74
75 #ifndef BooleanFlagOn
76 #define BooleanFlagOn(F,SF)   ((BOOLEAN)(((F) & (SF)) != 0))
77 #endif
78
79 #ifndef SetFlag
80 #define SetFlag(_F,_SF)       ((_F) |= (_SF))
81 #endif
82
83 #ifndef ClearFlag
84 #define ClearFlag(_F,_SF)     ((_F) &= ~(_SF))
85 #endif
86
87 #define QuadAlign(Ptr) (                \
88     ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \
89     )
90
91 #define MIN_WORKER_THREADS 5
92 #define MAX_WORKER_THREADS 512
93
94 typedef struct _worker_thread_info {
95
96     HANDLE hThread;
97
98     ULONG  Flags;
99
100     HANDLE hEvent;
101
102 } WorkerThreadInfo;
103
104 WorkerThreadInfo glWorkerThreadInfo[ MAX_WORKER_THREADS];
105
106 UINT   glThreadHandleIndex = 0;
107
108 HANDLE glDevHandle = INVALID_HANDLE_VALUE;
109
110 static DWORD Exit = false;
111
112 static DWORD ExitPending = false;
113
114 DWORD  dwOvEvIdx = 0;
115
116 extern "C" wchar_t RDR_UNCName[64]=L"AFS";
117
118 HANDLE RDR_SuspendEvent = INVALID_HANDLE_VALUE;
119
120 /* returns 0 on success */
121 extern "C" DWORD
122 RDR_Initialize(void)
123 {
124
125     DWORD dwRet = 0;
126     HKEY parmKey;
127     DWORD dummyLen;
128     DWORD numSvThreads = CM_CONFIGDEFAULT_SVTHREADS;
129
130     // Initialize the Suspend Event
131     RDR_SuspendEvent = CreateEvent( NULL,
132                                     TRUE, // manual reset event
133                                     TRUE, // signaled
134                                     NULL);
135
136     dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
137                          0, KEY_QUERY_VALUE, &parmKey);
138     if (dwRet == ERROR_SUCCESS) {
139         dummyLen = sizeof(numSvThreads);
140         dwRet = RegQueryValueEx(parmKey, TEXT("ServerThreads"), NULL, NULL,
141                                 (BYTE *) &numSvThreads, &dummyLen);
142
143         dummyLen = sizeof(RDR_UNCName);
144         dwRet = RegQueryValueExW(parmKey, L"NetbiosName", NULL, NULL,
145                                  (BYTE *) RDR_UNCName, &dummyLen);
146
147         RegCloseKey (parmKey);
148     }
149
150     // Initialize the Thread local storage index for the overlapped i/o
151     // Event Handle
152     dwOvEvIdx = TlsAlloc();
153
154     Exit = false;
155
156     //
157     // Launch our workers down to the
158     // filters control device for processing requests
159     //
160
161     dwRet = RDR_ProcessWorkerThreads(numSvThreads);
162
163     if (dwRet == ERROR_SUCCESS) {
164
165         RDR_InitIoctl();
166     }
167
168     return dwRet;
169 }
170
171 BOOL RDR_DeviceIoControl( HANDLE hDevice,
172                           DWORD dwIoControlCode,
173                           LPVOID lpInBuffer,
174                           DWORD nInBufferSize,
175                           LPVOID lpOutBuffer,
176                           DWORD nOutBufferSize,
177                           LPDWORD lpBytesReturned )
178 {
179     OVERLAPPED ov;
180     HANDLE hEvent;
181     BOOL rc = FALSE;
182     DWORD gle;
183
184     ZeroMemory(&ov, sizeof(OVERLAPPED));
185
186     hEvent = (HANDLE)TlsGetValue(dwOvEvIdx);
187     if (hEvent == NULL) {
188         hEvent = CreateEvent( NULL, TRUE, TRUE, NULL );
189         if (hEvent == INVALID_HANDLE_VALUE || hEvent == NULL)
190             return FALSE;
191         TlsSetValue( dwOvEvIdx, (LPVOID) hEvent );
192     }
193
194     ResetEvent( hEvent);
195     ov.hEvent = hEvent;
196     *lpBytesReturned = 0;
197
198     rc = DeviceIoControl( hDevice,
199                           dwIoControlCode,
200                           lpInBuffer,
201                           nInBufferSize,
202                           lpOutBuffer,
203                           nOutBufferSize,
204                           lpBytesReturned,
205                           &ov );
206     if ( !rc ) {
207         gle = GetLastError();
208
209         if ( gle == ERROR_IO_PENDING )
210             rc = GetOverlappedResult( hDevice, &ov, lpBytesReturned, TRUE );
211     }
212
213     return rc;
214 }
215
216 extern "C" DWORD
217 RDR_ShutdownFinal(void)
218 {
219
220     DWORD dwIndex = 0;
221
222     Exit = true;
223
224     //
225     // Close all the worker thread handles
226     //
227
228     while( dwIndex < glThreadHandleIndex)
229     {
230
231         CloseHandle( glWorkerThreadInfo[ dwIndex].hThread);
232
233         dwIndex++;
234     }
235
236     if( glDevHandle != INVALID_HANDLE_VALUE)
237     {
238
239         CloseHandle( glDevHandle);
240     }
241
242     return 0;
243 }
244
245 extern "C" DWORD
246 RDR_ShutdownNotify(void)
247 {
248
249     HANDLE hDevHandle = NULL;
250     DWORD bytesReturned;
251
252     //
253     // We use the global handle to the control device instance
254     //
255
256     hDevHandle = glDevHandle;
257
258
259     //
260     // First, notify the file system driver that
261     // we are shutting down.
262     //
263
264     ExitPending = true;
265
266     if( !RDR_DeviceIoControl( hDevHandle,
267                               IOCTL_AFS_SHUTDOWN,
268                               NULL,
269                               0,
270                               NULL,
271                               0,
272                               &bytesReturned ))
273     {
274         // log the error, nothing to do
275     }
276
277     return 0;
278 }
279
280 //
281 // Here we launch the worker threads for the given volume
282 //
283
284 DWORD
285 RDR_ProcessWorkerThreads(DWORD numThreads)
286 {
287     DWORD WorkerID;
288     HANDLE hEvent;
289     DWORD index = 0;
290     DWORD bytesReturned = 0;
291     DWORD dwRedirInitInfo;
292     AFSRedirectorInitInfo * redirInitInfo = NULL;
293     DWORD dwErr;
294
295     if (dwErr = RDR_SetInitParams(&redirInitInfo, &dwRedirInitInfo))
296         return dwErr;
297
298     glDevHandle = CreateFile( AFS_SYMLINK_W,
299                               GENERIC_READ | GENERIC_WRITE,
300                               FILE_SHARE_READ | FILE_SHARE_WRITE,
301                               NULL,
302                               OPEN_EXISTING,
303                               FILE_FLAG_OVERLAPPED,
304                               NULL);
305
306     if( glDevHandle == INVALID_HANDLE_VALUE)
307     {
308         free(redirInitInfo);
309         return GetLastError();
310     }
311
312     //
313     // Now call down to initialize the pool.
314     //
315
316     if( !RDR_DeviceIoControl( glDevHandle,
317                               IOCTL_AFS_INITIALIZE_CONTROL_DEVICE,
318                               NULL,
319                               0,
320                               NULL,
321                               0,
322                               &bytesReturned ))
323     {
324
325         CloseHandle( glDevHandle);
326
327         glDevHandle = NULL;
328
329         free(redirInitInfo);
330
331         return GetLastError();
332     }
333
334     //
335     // OK, now launch the workers
336     //
337
338     hEvent = CreateEvent( NULL,
339                           TRUE,
340                           FALSE,
341                           NULL);
342
343     //
344     // Here we create a pool of worker threads but you can create the pool with as many requests
345     // as you want
346     //
347
348     if (numThreads < MIN_WORKER_THREADS)
349         numThreads = MIN_WORKER_THREADS;
350     else if (numThreads > MAX_WORKER_THREADS)
351         numThreads = MAX_WORKER_THREADS;
352
353     for (index = 0; index < numThreads; index++)
354     {
355         //
356         // 20% of worker threads should be reserved for release extent
357         // event processing
358         //
359         glWorkerThreadInfo[ glThreadHandleIndex].Flags =
360             (glThreadHandleIndex % 5) ? 0 : AFS_REQUEST_RELEASE_THREAD;
361         glWorkerThreadInfo[ glThreadHandleIndex].hEvent = hEvent;
362         glWorkerThreadInfo[ glThreadHandleIndex].hThread =
363             CreateThread( NULL,
364                           0,
365                           RDR_RequestWorkerThread,
366                           (void *)&glWorkerThreadInfo[ glThreadHandleIndex],
367                           0,
368                           &WorkerID);
369
370         if( glWorkerThreadInfo[ glThreadHandleIndex].hThread != NULL)
371         {
372
373             //
374             // Wait for the thread to signal it is ready for processing
375             //
376
377             WaitForSingleObject( hEvent,
378                                  INFINITE);
379
380             glThreadHandleIndex++;
381
382             ResetEvent( hEvent);
383         }
384         else
385         {
386
387             //
388             // Perform cleanup specific to your application
389             //
390
391         }
392     }
393
394     if( !RDR_DeviceIoControl( glDevHandle,
395                               IOCTL_AFS_INITIALIZE_REDIRECTOR_DEVICE,
396                               redirInitInfo,
397                               dwRedirInitInfo,
398                               NULL,
399                               0,
400                               &bytesReturned ))
401     {
402
403         CloseHandle( glDevHandle);
404
405         glDevHandle = NULL;
406
407         free(redirInitInfo);
408
409         return GetLastError();
410     }
411
412     free(redirInitInfo);
413
414     return 0;
415 }
416
417 //
418 // Entry point for the worker thread
419 //
420
421 DWORD
422 WINAPI
423 RDR_RequestWorkerThread( LPVOID lpParameter)
424 {
425
426     HANDLE hDevHandle = NULL;
427     DWORD bytesReturned;
428     AFSCommRequest *requestBuffer;
429     bool bError = false;
430     WorkerThreadInfo * pInfo = (WorkerThreadInfo *)lpParameter;
431
432     //
433     // We use the global handle to the control device instance
434     //
435
436     hDevHandle = glDevHandle;
437
438     //
439     // Allocate a request buffer.
440     //
441
442     requestBuffer = (AFSCommRequest *)malloc( sizeof( AFSCommRequest) + AFS_PAYLOAD_BUFFER_SIZE);
443
444     if( requestBuffer)
445     {
446
447         //
448         // Here we simply signal back to the main thread that we ahve started
449         //
450
451         SetEvent( pInfo->hEvent);
452
453         //
454         // Process requests until we are told to stop
455         //
456
457         while( !Exit)
458         {
459
460             memset( requestBuffer, '\0', sizeof( AFSCommRequest) + AFS_PAYLOAD_BUFFER_SIZE);
461
462             requestBuffer->RequestFlags = pInfo->Flags;
463
464             if( !RDR_DeviceIoControl( hDevHandle,
465                                       IOCTL_AFS_PROCESS_IRP_REQUEST,
466                                       (void *)requestBuffer,
467                                       sizeof( AFSCommRequest),
468                                       (void *)requestBuffer,
469                                       sizeof( AFSCommRequest) + AFS_PAYLOAD_BUFFER_SIZE,
470                                       &bytesReturned ))
471             {
472
473                 //
474                 // Error condition back from driver
475                 //
476
477                 break;
478             }
479
480             WaitForSingleObject( RDR_SuspendEvent, INFINITE);
481
482             //
483             // Go process the request
484             //
485
486             if (!Exit)
487                 RDR_ProcessRequest( requestBuffer);
488         }
489
490         free( requestBuffer);
491     }
492
493     ExitThread( 0);
494
495     return 0;
496 }
497
498 //
499 // This is the entry point for the worker threads to process the request from the TC Filter driver
500 //
501
502 void
503 RDR_ProcessRequest( AFSCommRequest *RequestBuffer)
504 {
505
506     DWORD               bytesReturned;
507     DWORD               result = 0;
508     ULONG               ulIndex = 0;
509     ULONG               ulCreateFlags = 0;
510     AFSCommResult *     pResultCB = NULL;
511     AFSCommResult       stResultCB;
512     DWORD               dwResultBufferLength = 0;
513     AFSSetFileExtentsCB * SetFileExtentsResultCB = NULL;
514     AFSSetByteRangeLockResultCB *SetByteRangeLockResultCB = NULL;
515     WCHAR               wchBuffer[1024];
516     char *pBuffer = (char *)wchBuffer;
517     DWORD gle;
518     cm_user_t *         userp = NULL;
519     BOOL                bWow64 = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_WOW64) ? TRUE : FALSE;
520     BOOL                bFast  = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_FAST_REQUEST) ? TRUE : FALSE;
521     BOOL                bHoldFid = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_HOLD_FID) ? TRUE : FALSE;
522     BOOL                bFlushFile = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_FLUSH_FILE) ? TRUE : FALSE;
523     BOOL                bDeleteFile = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_FILE_DELETED) ? TRUE : FALSE;
524     BOOL                bUnlockFile = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_BYTE_RANGE_UNLOCK_ALL) ? TRUE : FALSE;
525     BOOL                bCheckOnly = (RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_CHECK_ONLY) ? TRUE : FALSE;
526     BOOL                bRetry = FALSE;
527     BOOL                bUnsupported = FALSE;
528     BOOL                bIsLocalSystem = (RequestBuffer->RequestFlags & AFS_REQUEST_LOCAL_SYSTEM_PAG) ? TRUE : FALSE;
529
530     userp = RDR_UserFromCommRequest(RequestBuffer);
531
532   retry:
533     //
534     // Build up the string to display based on the request type.
535     //
536
537     switch( RequestBuffer->RequestType)
538     {
539
540         case AFS_REQUEST_TYPE_DIR_ENUM:
541         {
542
543             AFSDirQueryCB *pQueryCB = (AFSDirQueryCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
544
545             if (afsd_logp->enabled) {
546                 swprintf( wchBuffer,
547                           L"ProcessRequest Processing AFS_REQUEST_TYPE_DIR_ENUM Index %08lX",
548                           RequestBuffer->RequestIndex);
549
550                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
551             }
552
553             //
554             // Here is where the content of the specific directory is enumerated.
555             //
556
557             RDR_EnumerateDirectory( userp, RequestBuffer->FileId,
558                                     pQueryCB, bWow64, bFast,
559                                     RequestBuffer->ResultBufferLength,
560                                     &pResultCB);
561             break;
562         }
563
564         case AFS_REQUEST_TYPE_EVAL_TARGET_BY_ID:
565         {
566             AFSEvalTargetCB *pEvalTargetCB = (AFSEvalTargetCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
567
568             if (afsd_logp->enabled) {
569                 swprintf( wchBuffer,
570                           L"ProcessRequest Processing AFS_REQUEST_TYPE_EVAL_TARGET_BY_ID Index %08lX",
571                           RequestBuffer->RequestIndex);
572
573                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
574             }
575             //
576             // Here is where the specified node is evaluated.
577             //
578
579             RDR_EvaluateNodeByID( userp, pEvalTargetCB->ParentId,
580                                   RequestBuffer->FileId,
581                                   bWow64, bFast, bHoldFid,
582                                   RequestBuffer->ResultBufferLength,
583                                   &pResultCB);
584             break;
585         }
586
587         case AFS_REQUEST_TYPE_EVAL_TARGET_BY_NAME:
588         {
589             AFSEvalTargetCB *pEvalTargetCB = (AFSEvalTargetCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
590
591             if (afsd_logp->enabled) {
592                 swprintf( wchBuffer,
593                           L"ProcessRequest Processing AFS_REQUEST_TYPE_EVAL_TARGET_BY_NAME Index %08lX",
594                           RequestBuffer->RequestIndex);
595
596                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
597             }
598             //
599             // Here is where the specified node is evaluated.
600             //
601
602             RDR_EvaluateNodeByName( userp, pEvalTargetCB->ParentId,
603                                     RequestBuffer->Name,
604                                     RequestBuffer->NameLength,
605                                     RequestBuffer->RequestFlags & AFS_REQUEST_FLAG_CASE_SENSITIVE ? TRUE : FALSE,
606                                     bWow64, bFast, bHoldFid,
607                                     RequestBuffer->ResultBufferLength,
608                                     &pResultCB);
609             break;
610         }
611
612         case AFS_REQUEST_TYPE_CREATE_FILE:
613         {
614
615             AFSFileCreateCB *pCreateCB = (AFSFileCreateCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
616
617             WCHAR wchFileName[ 256];
618
619             if (afsd_logp->enabled) {
620                 memset( wchFileName, '\0', 256 * sizeof( WCHAR));
621
622                 memcpy( wchFileName,
623                         RequestBuffer->Name,
624                         RequestBuffer->NameLength);
625
626                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_CREATE_FILE Index %08lX File %S",
627                           RequestBuffer->RequestIndex, wchFileName);
628
629                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
630             }
631
632             RDR_CreateFileEntry( userp,
633                                  RequestBuffer->Name,
634                                  RequestBuffer->NameLength,
635                                  pCreateCB,
636                                  bWow64,
637                                  bHoldFid,
638                                  RequestBuffer->ResultBufferLength,
639                                  &pResultCB);
640
641             break;
642         }
643
644         case AFS_REQUEST_TYPE_UPDATE_FILE:
645         {
646
647             AFSFileUpdateCB *pUpdateCB = (AFSFileUpdateCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
648
649             if (afsd_logp->enabled) {
650                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_UPDATE_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
651                           RequestBuffer->RequestIndex,
652                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
653                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
654
655                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
656             }
657
658             RDR_UpdateFileEntry( userp, RequestBuffer->FileId,
659                                  pUpdateCB,
660                                  bWow64,
661                                  RequestBuffer->ResultBufferLength,
662                                  &pResultCB);
663
664             break;
665         }
666
667         case AFS_REQUEST_TYPE_DELETE_FILE:
668         {
669
670             AFSFileDeleteCB *pDeleteCB = (AFSFileDeleteCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
671
672             if (afsd_logp->enabled) {
673                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_DELETE_FILE Index %08lX %08lX.%08lX.%08lX.%08lX CheckOnly %X",
674                           RequestBuffer->RequestIndex,
675                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
676                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
677                           bCheckOnly);
678
679                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
680             }
681
682             RDR_DeleteFileEntry( userp,
683                                  pDeleteCB->ParentId,
684                                  pDeleteCB->ProcessId,
685                                  RequestBuffer->Name,
686                                  RequestBuffer->NameLength,
687                                  bWow64,
688                                  bCheckOnly,
689                                  RequestBuffer->ResultBufferLength,
690                                  &pResultCB);
691
692             break;
693         }
694
695         case AFS_REQUEST_TYPE_RENAME_FILE:
696         {
697
698             AFSFileRenameCB *pFileRenameCB = (AFSFileRenameCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
699
700             if (afsd_logp->enabled) {
701                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_RENAME_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX NameLength %08lX Name %*S",
702                           RequestBuffer->RequestIndex,
703                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
704                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
705                           RequestBuffer->NameLength, (int)RequestBuffer->NameLength, RequestBuffer->Name);
706
707                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
708             }
709
710             RDR_RenameFileEntry( userp,
711                                  RequestBuffer->Name,
712                                  RequestBuffer->NameLength,
713                                  RequestBuffer->FileId,
714                                  pFileRenameCB,
715                                  bWow64,
716                                  RequestBuffer->ResultBufferLength,
717                                  &pResultCB);
718
719             break;
720         }
721
722         case AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS:
723         {
724
725             AFSRequestExtentsCB *pFileRequestExtentsCB = (AFSRequestExtentsCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
726
727             if (afsd_logp->enabled) {
728                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS Index %08lX File %08lX.%08lX.%08lX.%08lX %S",
729                           RequestBuffer->RequestIndex,
730                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
731                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
732                           BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS) ? L"Sync" : L"Async");
733
734                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
735             }
736
737             if (BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS))
738                 osi_panic("SYNCHRONOUS AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS not supported",
739                           __FILE__, __LINE__);
740             else
741                 bRetry = RDR_RequestFileExtentsAsync( userp, RequestBuffer->FileId,
742                                                       pFileRequestExtentsCB,
743                                                       bWow64,
744                                                       &dwResultBufferLength,
745                                                       &SetFileExtentsResultCB );
746             break;
747         }
748
749         case AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS:
750         {
751
752             AFSReleaseExtentsCB *pFileReleaseExtentsCB = (AFSReleaseExtentsCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
753
754             if (afsd_logp->enabled) {
755                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS Index %08lX File %08lX.%08lX.%08lX.%08lX",
756                           RequestBuffer->RequestIndex,
757                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
758                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
759
760                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
761             }
762
763             RDR_ReleaseFileExtents( userp, RequestBuffer->FileId,
764                                     pFileReleaseExtentsCB,
765                                     bWow64,
766                                     RequestBuffer->ResultBufferLength,
767                                     &pResultCB);
768
769             break;
770         }
771
772         case AFS_REQUEST_TYPE_FLUSH_FILE:
773         {
774             if (afsd_logp->enabled) {
775                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_FLUSH_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
776                           RequestBuffer->RequestIndex,
777                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
778                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
779
780                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
781             }
782
783             RDR_FlushFileEntry( userp, RequestBuffer->FileId,
784                                 bWow64,
785                                 RequestBuffer->ResultBufferLength,
786                                 &pResultCB);
787             break;
788         }
789
790         case AFS_REQUEST_TYPE_OPEN_FILE:
791         {
792             AFSFileOpenCB *pFileOpenCB = (AFSFileOpenCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
793
794             if (afsd_logp->enabled) {
795                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_OPEN_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
796                           RequestBuffer->RequestIndex,
797                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
798                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
799
800                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
801             }
802
803             RDR_OpenFileEntry( userp, RequestBuffer->FileId,
804                                pFileOpenCB,
805                                bWow64,
806                                bHoldFid,
807                                RequestBuffer->ResultBufferLength,
808                                &pResultCB);
809
810             break;
811         }
812
813         case AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS:
814         {
815             AFSFileAccessReleaseCB *pFileAccessReleaseCB = (AFSFileAccessReleaseCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
816
817             if (afsd_logp->enabled) {
818                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS Index %08lX File %08lX.%08lX.%08lX.%08lX",
819                           RequestBuffer->RequestIndex,
820                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
821                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
822
823                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
824             }
825
826             RDR_ReleaseFileAccess( userp,
827                                    RequestBuffer->FileId,
828                                    pFileAccessReleaseCB,
829                                    bWow64,
830                                    RequestBuffer->ResultBufferLength,
831                                    &pResultCB);
832
833             break;
834         }
835
836         case AFS_REQUEST_TYPE_PIOCTL_OPEN:
837         {
838             AFSPIOCtlOpenCloseRequestCB *pPioctlCB = (AFSPIOCtlOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
839
840             if (afsd_logp->enabled) {
841                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_OPEN Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
842                           RequestBuffer->RequestIndex,
843                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
844                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
845
846                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
847             }
848
849             RDR_PioctlOpen( userp,
850                             RequestBuffer->FileId,
851                             pPioctlCB,
852                             bWow64,
853                             RequestBuffer->ResultBufferLength,
854                             &pResultCB);
855             break;
856         }
857
858         case AFS_REQUEST_TYPE_PIOCTL_WRITE:
859         {
860             AFSPIOCtlIORequestCB *pPioctlCB = (AFSPIOCtlIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
861
862             if (afsd_logp->enabled) {
863                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_WRITE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
864                           RequestBuffer->RequestIndex,
865                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
866                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
867
868                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
869             }
870
871             RDR_PioctlWrite( userp,
872                              RequestBuffer->FileId,
873                              pPioctlCB,
874                              bWow64,
875                              RequestBuffer->ResultBufferLength,
876                              &pResultCB);
877             break;
878         }
879
880     case AFS_REQUEST_TYPE_PIOCTL_READ:
881             {
882                 AFSPIOCtlIORequestCB *pPioctlCB = (AFSPIOCtlIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
883
884                 if (afsd_logp->enabled) {
885                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_READ Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
886                               RequestBuffer->RequestIndex,
887                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
888                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
889
890                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
891                 }
892
893                 RDR_PioctlRead( userp,
894                                 RequestBuffer->FileId,
895                                 pPioctlCB,
896                                 bWow64,
897                                 bIsLocalSystem,
898                                 RequestBuffer->ResultBufferLength,
899                                 &pResultCB);
900                 break;
901             }
902
903     case AFS_REQUEST_TYPE_PIOCTL_CLOSE:
904             {
905                 AFSPIOCtlOpenCloseRequestCB *pPioctlCB = (AFSPIOCtlOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
906
907                 if (afsd_logp->enabled) {
908                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_CLOSE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
909                               RequestBuffer->RequestIndex,
910                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
911                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
912
913                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
914                 }
915
916                 RDR_PioctlClose( userp,
917                                 RequestBuffer->FileId,
918                                 pPioctlCB,
919                                 bWow64,
920                                 RequestBuffer->ResultBufferLength,
921                                 &pResultCB);
922                 break;
923             }
924
925
926     case AFS_REQUEST_TYPE_BYTE_RANGE_LOCK:
927             {
928                 if (afsd_logp->enabled) {
929                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_BYTE_RANGE_LOCK Index %08lX File %08lX.%08lX.%08lX.%08lX %S",
930                               RequestBuffer->RequestIndex,
931                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
932                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
933                               BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS) ? L"Sync" : L"Async");
934
935                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
936                 }
937
938                 AFSByteRangeLockRequestCB *pBRLRequestCB = (AFSByteRangeLockRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
939
940                 RDR_ByteRangeLockSync( userp,
941                                        RequestBuffer->FileId,
942                                        pBRLRequestCB,
943                                        bWow64,
944                                        RequestBuffer->ResultBufferLength,
945                                        &pResultCB);
946
947                 break;
948             }
949
950     case AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK:
951             {
952                 AFSByteRangeUnlockRequestCB *pBRURequestCB = (AFSByteRangeUnlockRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
953
954                 if (afsd_logp->enabled) {
955                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK Index %08lX File %08lX.%08lX.%08lX.%08lX",
956                               RequestBuffer->RequestIndex,
957                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
958                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
959
960                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
961                 }
962
963                 RDR_ByteRangeUnlock( userp,
964                                      RequestBuffer->FileId,
965                                      pBRURequestCB,
966                                      bWow64,
967                                      RequestBuffer->ResultBufferLength,
968                                      &pResultCB);
969                 break;
970             }
971
972     case AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK_ALL:
973             {
974                 AFSByteRangeUnlockRequestCB *pBRURequestCB = (AFSByteRangeUnlockRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
975
976                 if (afsd_logp->enabled) {
977                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK_ALL Index %08lX File %08lX.%08lX.%08lX.%08lX",
978                               RequestBuffer->RequestIndex,
979                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
980                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
981
982                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
983                 }
984
985                 RDR_ByteRangeUnlockAll( userp,
986                                         RequestBuffer->FileId,
987                                         pBRURequestCB,
988                                         bWow64,
989                                         RequestBuffer->ResultBufferLength,
990                                         &pResultCB);
991                 break;
992             }
993
994     case AFS_REQUEST_TYPE_GET_VOLUME_INFO:
995             {
996                 if (afsd_logp->enabled) {
997                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_GET_VOLUME_INFO Index %08lX File %08lX.%08lX.%08lX.%08lX",
998                               RequestBuffer->RequestIndex,
999                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1000                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1001
1002                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1003                 }
1004
1005                 RDR_GetVolumeInfo( userp,
1006                                    RequestBuffer->FileId,
1007                                    bWow64,
1008                                    RequestBuffer->ResultBufferLength,
1009                                    &pResultCB);
1010                 break;
1011             }
1012
1013     case AFS_REQUEST_TYPE_HOLD_FID:
1014             {
1015
1016                 AFSHoldFidRequestCB *pHoldFidCB = (AFSHoldFidRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1017
1018                 if (afsd_logp->enabled) {
1019                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_HOLD_FID Index %08lX",
1020                               RequestBuffer->RequestIndex);
1021
1022                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1023                 }
1024
1025                 RDR_HoldFid( userp,
1026                              pHoldFidCB,
1027                              bFast,
1028                              RequestBuffer->ResultBufferLength,
1029                              &pResultCB);
1030
1031                 break;
1032             }
1033
1034     case AFS_REQUEST_TYPE_RELEASE_FID:
1035             {
1036
1037                 AFSReleaseFidRequestCB *pReleaseFidCB = (AFSReleaseFidRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1038
1039                 if (afsd_logp->enabled) {
1040                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_RELEASE_FID Index %08lX",
1041                               RequestBuffer->RequestIndex);
1042
1043                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1044                 }
1045
1046                 RDR_ReleaseFid( userp,
1047                                 pReleaseFidCB,
1048                                 bFast,
1049                                 RequestBuffer->ResultBufferLength,
1050                                 &pResultCB);
1051
1052                 break;
1053             }
1054
1055     case AFS_REQUEST_TYPE_CLEANUP_PROCESSING:
1056             {
1057
1058                 AFSFileCleanupCB *pCleanupCB = (AFSFileCleanupCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1059
1060                 if (afsd_logp->enabled) {
1061                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_CLEANUP_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
1062                               RequestBuffer->RequestIndex,
1063                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1064                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1065
1066                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1067                 }
1068
1069                 RDR_CleanupFileEntry( userp,
1070                                       RequestBuffer->FileId,
1071                                       RequestBuffer->Name,
1072                                       RequestBuffer->NameLength,
1073                                       pCleanupCB,
1074                                       bWow64,
1075                                       bFlushFile,
1076                                       bDeleteFile,
1077                                       bUnlockFile,
1078                                       RequestBuffer->ResultBufferLength,
1079                                       &pResultCB);
1080
1081                 break;
1082             }
1083
1084     case AFS_REQUEST_TYPE_PIPE_OPEN:
1085             {
1086                 AFSPipeOpenCloseRequestCB *pPipeCB = (AFSPipeOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1087
1088                 if (afsd_logp->enabled) {
1089                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_OPEN Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
1090                               RequestBuffer->RequestIndex,
1091                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1092                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1093
1094                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1095                 }
1096
1097                 RDR_PipeOpen( userp,
1098                               RequestBuffer->FileId,
1099                               RequestBuffer->Name,
1100                               RequestBuffer->NameLength,
1101                               pPipeCB,
1102                               bWow64,
1103                               RequestBuffer->ResultBufferLength,
1104                               &pResultCB);
1105                 break;
1106             }
1107
1108     case AFS_REQUEST_TYPE_PIPE_WRITE:
1109             {
1110                 AFSPipeIORequestCB *pPipeCB = (AFSPipeIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1111                 BYTE *pPipeData = ((BYTE *)RequestBuffer->Name + RequestBuffer->DataOffset + sizeof(AFSPipeIORequestCB));
1112
1113                 if (afsd_logp->enabled) {
1114                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_WRITE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
1115                               RequestBuffer->RequestIndex,
1116                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1117                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1118
1119                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1120                 }
1121
1122                 RDR_PipeWrite( userp,
1123                                RequestBuffer->FileId,
1124                                pPipeCB,
1125                                pPipeData,
1126                                bWow64,
1127                                RequestBuffer->ResultBufferLength,
1128                                &pResultCB);
1129                 break;
1130             }
1131
1132     case AFS_REQUEST_TYPE_PIPE_READ:
1133             {
1134                 AFSPipeIORequestCB *pPipeCB = (AFSPipeIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1135
1136                 if (afsd_logp->enabled) {
1137                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_READ Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
1138                               RequestBuffer->RequestIndex,
1139                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1140                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1141
1142                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1143                 }
1144
1145                 RDR_PipeRead( userp,
1146                               RequestBuffer->FileId,
1147                               pPipeCB,
1148                               bWow64,
1149                               RequestBuffer->ResultBufferLength,
1150                               &pResultCB);
1151                 break;
1152             }
1153
1154     case AFS_REQUEST_TYPE_PIPE_CLOSE:
1155             {
1156                 AFSPipeOpenCloseRequestCB *pPipeCB = (AFSPipeOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1157
1158                 if (afsd_logp->enabled) {
1159                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_CLOSE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
1160                               RequestBuffer->RequestIndex,
1161                               RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1162                               RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1163
1164                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1165                 }
1166
1167                 RDR_PipeClose( userp,
1168                                 RequestBuffer->FileId,
1169                                 pPipeCB,
1170                                 bWow64,
1171                                 RequestBuffer->ResultBufferLength,
1172                                 &pResultCB);
1173                 break;
1174             }
1175
1176
1177     case AFS_REQUEST_TYPE_PIPE_TRANSCEIVE:
1178             {
1179                 AFSPipeIORequestCB *pPipeCB = (AFSPipeIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1180                 BYTE *pPipeData = ((BYTE *)RequestBuffer->Name + RequestBuffer->DataOffset + sizeof(AFSPipeIORequestCB));
1181
1182                 if (afsd_logp->enabled) {
1183                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_TRANSCEIVE Index %08lX",
1184                               RequestBuffer->RequestIndex);
1185
1186                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1187                 }
1188
1189                 RDR_PipeTransceive( userp,
1190                                     RequestBuffer->FileId,
1191                                     pPipeCB,
1192                                     pPipeData,
1193                                     bWow64,
1194                                     RequestBuffer->ResultBufferLength,
1195                                     &pResultCB);
1196                 break;
1197             }
1198
1199     case AFS_REQUEST_TYPE_PIPE_QUERY_INFO:
1200             {
1201                 AFSPipeInfoRequestCB *pPipeInfoCB = (AFSPipeInfoRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1202
1203                 if (afsd_logp->enabled) {
1204                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_QUERY_INFO Index %08lX",
1205                               RequestBuffer->RequestIndex);
1206
1207                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1208                 }
1209
1210                 RDR_PipeQueryInfo( userp,
1211                                    RequestBuffer->FileId,
1212                                    pPipeInfoCB,
1213                                    bWow64,
1214                                    RequestBuffer->ResultBufferLength,
1215                                    &pResultCB);
1216                 break;
1217             }
1218
1219     case AFS_REQUEST_TYPE_PIPE_SET_INFO:
1220             {
1221                 AFSPipeInfoRequestCB *pPipeInfoCB = (AFSPipeInfoRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1222                 BYTE *pPipeData = ((BYTE *)RequestBuffer->Name + RequestBuffer->DataOffset + sizeof(AFSPipeInfoRequestCB));
1223
1224                 if (afsd_logp->enabled) {
1225                     swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_SET_INFO Index %08lX",
1226                               RequestBuffer->RequestIndex);
1227
1228                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1229                 }
1230
1231                 RDR_PipeSetInfo( userp,
1232                                  RequestBuffer->FileId,
1233                                  pPipeInfoCB,
1234                                  pPipeData,
1235                                  bWow64,
1236                                  RequestBuffer->ResultBufferLength,
1237                                  &pResultCB);
1238
1239                 break;
1240             }
1241
1242     default:
1243             bUnsupported = TRUE;
1244
1245             if (afsd_logp->enabled) {
1246                 swprintf( wchBuffer, L"ProcessRequest Received unknown request type %08lX Index %08lX",
1247                           RequestBuffer->RequestType,
1248                           RequestBuffer->RequestIndex);
1249
1250                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1251             }
1252
1253             break;
1254     }
1255
1256     if( BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS))
1257     {
1258         if (pResultCB == NULL) {
1259             // We failed probably due to a memory allocation error
1260             // unless the unsupported flag was set.
1261             pResultCB = &stResultCB;
1262             memset(&stResultCB, 0, sizeof(stResultCB));
1263             if ( bUnsupported )
1264                 pResultCB->ResultStatus = STATUS_NOT_IMPLEMENTED;
1265             else
1266                 pResultCB->ResultStatus = STATUS_NO_MEMORY;
1267         }
1268
1269         //
1270         // This is how the filter associates the response information passed in the IOCtl below to the
1271         // original call. This request index is setup by the filter and should not be modified, otherwise the
1272         // filter will not be able to locate the request in its internal queue and the blocking thread will
1273         // not be awakened
1274         //
1275
1276         pResultCB->RequestIndex = RequestBuffer->RequestIndex;
1277
1278         if (afsd_logp->enabled) {
1279             swprintf( wchBuffer,
1280                       L"ProcessRequest Responding to Index %08lX Length %08lX",
1281                       pResultCB->RequestIndex,
1282                       pResultCB->ResultBufferLength);
1283
1284             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1285         }
1286
1287         //
1288         // Now post the result back to the driver.
1289         //
1290
1291         if( !RDR_DeviceIoControl( glDevHandle,
1292                                   IOCTL_AFS_PROCESS_IRP_RESULT,
1293                                   (void *)pResultCB,
1294                                   sizeof( AFSCommResult) + pResultCB->ResultBufferLength,
1295                                   (void *)NULL,
1296                                   0,
1297                                   &bytesReturned ))
1298         {
1299             char *pBuffer = (char *)wchBuffer;
1300             gle = GetLastError();
1301             if (afsd_logp->enabled) {
1302                 swprintf( wchBuffer,
1303                           L"Failed to post IOCTL_AFS_PROCESS_IRP_RESULT gle %X", gle);
1304                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1305             }
1306
1307             sprintf( pBuffer,
1308                      "Failed to post IOCTL_AFS_PROCESS_IRP_RESULT gle %X",
1309                      GetLastError());
1310             osi_panic(pBuffer, __FILE__, __LINE__);
1311         }
1312
1313     }
1314     else if (RequestBuffer->RequestType == AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS) {
1315
1316         if (SetFileExtentsResultCB) {
1317
1318             if (1 || afsd_logp->enabled) {
1319                 if (SetFileExtentsResultCB->ResultStatus != 0)
1320                     swprintf( wchBuffer,
1321                           L"ProcessRequest Responding Asynchronously with FAILURE to REQUEST_FILE_EXTENTS Index %08lX Count %08lX Status %08lX",
1322                           RequestBuffer->RequestIndex, SetFileExtentsResultCB->ExtentCount, SetFileExtentsResultCB->ResultStatus);
1323                 else
1324                     swprintf( wchBuffer,
1325                           L"ProcessRequest Responding Asynchronously with SUCCESS to REQUEST_FILE_EXTENTS Index %08lX Count %08lX",
1326                           RequestBuffer->RequestIndex, SetFileExtentsResultCB->ExtentCount);
1327
1328                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1329             }
1330
1331             if( (SetFileExtentsResultCB->ExtentCount != 0 ||
1332                  SetFileExtentsResultCB->ResultStatus != 0) &&
1333                 !RDR_DeviceIoControl( glDevHandle,
1334                                        IOCTL_AFS_SET_FILE_EXTENTS,
1335                                       (void *)SetFileExtentsResultCB,
1336                                       dwResultBufferLength,
1337                                       (void *)NULL,
1338                                       0,
1339                                       &bytesReturned ))
1340             {
1341                 gle = GetLastError();
1342                 if (afsd_logp->enabled) {
1343                     swprintf( wchBuffer,
1344                               L"Failed to post IOCTL_AFS_SET_FILE_EXTENTS gle %X",
1345                               gle);
1346                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1347                 }
1348
1349                 // The file system returns an error when it can't find the FID
1350                 // This is a bug in the file system but we should try to avoid
1351                 // the crash and clean up our own memory space.
1352                 //
1353                 // Since we couldn't deliver the extents to the file system
1354                 // we should release them.
1355                 if ( SetFileExtentsResultCB->ExtentCount != 0)
1356                 {
1357                     RDR_ReleaseFailedSetFileExtents( userp,
1358                                                  SetFileExtentsResultCB,
1359                                                  dwResultBufferLength);
1360                 }
1361
1362                 if (gle != ERROR_GEN_FAILURE) {
1363                     sprintf( pBuffer,
1364                              "Failed to post IOCTL_AFS_SET_FILE_EXTENTS gle %X",
1365                              gle);
1366                     osi_panic(pBuffer, __FILE__, __LINE__);
1367                 }
1368             }
1369
1370             free(SetFileExtentsResultCB);
1371
1372       } else {
1373           /* Must be out of memory */
1374           if (afsd_logp->enabled) {
1375               swprintf( wchBuffer,
1376                         L"ProcessRequest Responding Asynchronously STATUS_NO_MEMORY to REQUEST_FILE_EXTENTS Index %08lX",
1377                         RequestBuffer->RequestIndex);
1378
1379               osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1380           }
1381
1382           RDR_SetFileStatus( (cm_fid_t *)&RequestBuffer->FileId, STATUS_NO_MEMORY);
1383        }
1384     }
1385     else if (RequestBuffer->RequestType == AFS_REQUEST_TYPE_BYTE_RANGE_LOCK) {
1386
1387         if (afsd_logp->enabled) {
1388             swprintf( wchBuffer,
1389                       L"ProcessRequest Responding Asynchronously to REQUEST_TYPE_BYTE_RANGELOCK Index %08lX",
1390                       RequestBuffer->RequestIndex);
1391
1392             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1393         }
1394
1395
1396         if (SetByteRangeLockResultCB) {
1397
1398             if( !RDR_DeviceIoControl( glDevHandle,
1399                                   IOCTL_AFS_SET_BYTE_RANGE_LOCKS,
1400                                   (void *)SetByteRangeLockResultCB,
1401                                   dwResultBufferLength,
1402                                   (void *)NULL,
1403                                   0,
1404                                   &bytesReturned ))
1405             {
1406                 gle = GetLastError();
1407
1408                 if (afsd_logp->enabled) {
1409                     swprintf( wchBuffer,
1410                               L"Failed to post IOCTL_AFS_SET_BYTE_RANGE_LOCKS gle 0x%x", gle);
1411                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1412                 }
1413
1414
1415                 // TODO - instead of a panic we should release the locks
1416                 sprintf( pBuffer,
1417                          "Failed to post IOCTL_AFS_SET_BYTE_RANGE_LOCKS gle %X", gle);
1418                 osi_panic(pBuffer, __FILE__, __LINE__);
1419             }
1420
1421             free(SetByteRangeLockResultCB);
1422         } else {
1423             /* Must be out of memory */
1424             AFSSetByteRangeLockResultCB SetByteRangeLockResultCB;
1425
1426             dwResultBufferLength = sizeof(AFSSetByteRangeLockResultCB);
1427             memset( &SetByteRangeLockResultCB, '\0', dwResultBufferLength );
1428             SetByteRangeLockResultCB.FileId = RequestBuffer->FileId;
1429             SetByteRangeLockResultCB.Result[0].Status = STATUS_NO_MEMORY;
1430
1431             if( !RDR_DeviceIoControl( glDevHandle,
1432                                       IOCTL_AFS_SET_BYTE_RANGE_LOCKS,
1433                                       (void *)&SetByteRangeLockResultCB,
1434                                       dwResultBufferLength,
1435                                       (void *)NULL,
1436                                       0,
1437                                       &bytesReturned ))
1438             {
1439                 gle = GetLastError();
1440
1441                 if (afsd_logp->enabled) {
1442                     swprintf( wchBuffer,
1443                               L"Failed to post IOCTL_AFS_SET_BYTE_RANGE_LOCKS gle 0x%x", gle);
1444                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1445                 }
1446
1447                 /* We were out of memory - nothing to do */
1448             }
1449         }
1450     }
1451     else {
1452
1453         if (afsd_logp->enabled) {
1454             swprintf( wchBuffer,
1455                       L"ProcessRequest Not responding to async Index %08lX",
1456                       RequestBuffer->RequestIndex);
1457
1458             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1459         }
1460     }
1461
1462     if (bRetry)
1463         goto retry;
1464
1465     if (userp)
1466         RDR_ReleaseUser(userp);
1467
1468
1469     if( pResultCB && pResultCB != &stResultCB)
1470     {
1471
1472         free( pResultCB);
1473     }
1474     return;
1475 }
1476
1477
1478 extern "C" DWORD
1479 RDR_SetFileExtents( AFSSetFileExtentsCB *pSetFileExtentsResultCB,
1480                     DWORD dwResultBufferLength)
1481 {
1482     WCHAR wchBuffer[1024];
1483     DWORD bytesReturned;
1484     DWORD gle;
1485
1486     if (1 || afsd_logp->enabled) {
1487         if (pSetFileExtentsResultCB->ResultStatus != 0)
1488             swprintf( wchBuffer,
1489                L"RDR_SetFileExtents IOCTL_AFS_SET_FILE_EXTENTS FAILURE Count %08lX Status %08lX",
1490                pSetFileExtentsResultCB->ExtentCount, pSetFileExtentsResultCB->ResultStatus);
1491         else
1492             swprintf( wchBuffer,
1493                L"RDR_SetFileExtents IOCTL_AFS_SET_FILE_EXTENTS SUCCESS Count %08lX",
1494                pSetFileExtentsResultCB->ExtentCount);
1495
1496         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1497     }
1498
1499     if( !RDR_DeviceIoControl( glDevHandle,
1500                               IOCTL_AFS_SET_FILE_EXTENTS,
1501                               (void *)pSetFileExtentsResultCB,
1502                               dwResultBufferLength,
1503                               (void *)NULL,
1504                               0,
1505                               &bytesReturned ))
1506     {
1507         gle = GetLastError();
1508         return gle;
1509     }
1510
1511     return 0;
1512 }
1513
1514
1515 extern "C" DWORD
1516 RDR_SetFileStatus( cm_fid_t *fidp,
1517                    DWORD dwStatus)
1518 {
1519     WCHAR               wchBuffer[1024];
1520     AFSExtentFailureCB  SetFileStatusCB;
1521     DWORD               bytesReturned;
1522     DWORD               gle;
1523     AFSFileID          *pFileId = (AFSFileID *)fidp;
1524
1525     SetFileStatusCB.FileId = *pFileId;
1526     SetFileStatusCB.FailureStatus = dwStatus;
1527
1528     if (afsd_logp->enabled) {
1529         swprintf( wchBuffer, L"RDR_SetFileStatus IOCTL_AFS_EXTENT_FAILURE_CB Fid %08lX.%08lX.%08lX.%08lX Status 0x%lX",
1530                   pFileId->Cell, pFileId->Volume,
1531                   pFileId->Vnode, pFileId->Unique,
1532                   dwStatus);
1533
1534         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1535     }
1536
1537     if( !RDR_DeviceIoControl( glDevHandle,
1538                               IOCTL_AFS_SET_FILE_EXTENT_FAILURE,
1539                               (void *)&SetFileStatusCB,
1540                               sizeof(AFSExtentFailureCB),
1541                               (void *)NULL,
1542                               0,
1543                               &bytesReturned ))
1544     {
1545         gle = GetLastError();
1546         return gle;
1547     }
1548
1549     return 0;
1550 }
1551
1552
1553 extern "C" DWORD
1554 RDR_RequestExtentRelease(cm_fid_t *fidp, LARGE_INTEGER numOfHeldExtents, DWORD numOfExtents, AFSFileExtentCB *extentList)
1555 {
1556
1557     HANDLE hDevHandle = NULL;
1558     DWORD bytesReturned;
1559     AFSReleaseFileExtentsCB *requestBuffer = NULL;
1560     AFSReleaseFileExtentsResultCB *responseBuffer = NULL;
1561     DWORD requestBufferLen, responseBufferLen;
1562     bool bError = false;
1563     DWORD rc = 0;
1564     WCHAR wchBuffer[256];
1565     DWORD gle;
1566
1567     if (ExitPending) {
1568         if (afsd_logp->enabled) {
1569             swprintf( wchBuffer,
1570                       L"IOCTL_AFS_RELEASE_FILE_EXTENTS request ignored due to shutdown pending");
1571
1572             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1573         }
1574
1575         OutputDebugString(L"RDR_RequestExtentRequest ignored - shutdown pending\n");
1576         return CM_ERROR_WOULDBLOCK;
1577     }
1578
1579     if (afsd_logp->enabled) {
1580         swprintf( wchBuffer,
1581                   L"IOCTL_AFS_RELEASE_FILE_EXTENTS request - number %08lX",
1582                   numOfExtents);
1583
1584         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1585     }
1586
1587     //
1588     // We use the global handle to the control device instance
1589     //
1590
1591     hDevHandle = glDevHandle;
1592
1593     //
1594     // Allocate a request buffer.
1595     //
1596
1597     requestBufferLen = sizeof( AFSReleaseFileExtentsCB) + sizeof(AFSFileExtentCB) * numOfExtents;
1598     requestBuffer = (AFSReleaseFileExtentsCB *)malloc( requestBufferLen);
1599     responseBufferLen = (sizeof( AFSReleaseFileExtentsResultCB) + sizeof( AFSReleaseFileExtentsResultFileCB)) * numOfExtents;
1600     responseBuffer = (AFSReleaseFileExtentsResultCB *)malloc( responseBufferLen);
1601
1602
1603     if( requestBuffer && responseBuffer)
1604     {
1605
1606         memset( requestBuffer, '\0', sizeof( AFSReleaseFileExtentsCB));
1607         memset( responseBuffer, '\0', responseBufferLen);
1608
1609         // If there is a FID provided, use it
1610         if (fidp && extentList)
1611         {
1612             RDR_fid2FID( fidp, &requestBuffer->FileId);
1613
1614             memcpy(&requestBuffer->FileExtents, extentList, numOfExtents * sizeof(AFSFileExtentCB));
1615
1616             requestBuffer->Flags = 0;
1617         } else {
1618
1619             requestBuffer->Flags = AFS_RELEASE_EXTENTS_FLAGS_RELEASE_ALL;
1620         }
1621
1622         // Set the number of extents to be freed
1623         // Leave the rest of the structure as zeros to indicate free anything
1624         requestBuffer->ExtentCount = numOfExtents;
1625
1626         requestBuffer->HeldExtentCount = numOfHeldExtents;
1627
1628         if( !RDR_DeviceIoControl( hDevHandle,
1629                                   IOCTL_AFS_RELEASE_FILE_EXTENTS,
1630                                   (void *)requestBuffer,
1631                                   requestBufferLen,
1632                                   (void *)responseBuffer,
1633                                   responseBufferLen,
1634                                   &bytesReturned ))
1635         {
1636             //
1637             // Error condition back from driver
1638             //
1639             if (afsd_logp->enabled) {
1640                 gle = GetLastError();
1641                 swprintf( wchBuffer,
1642                           L"Failed to post IOCTL_AFS_RELEASE_FILE_EXTENTS - gle 0x%x", gle);
1643                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1644             }
1645             rc = -1;
1646             goto cleanup;
1647         }
1648
1649         //
1650         // Go process the request
1651         //
1652
1653         if (afsd_logp->enabled) {
1654             swprintf( wchBuffer,
1655                       L"IOCTL_AFS_RELEASE_FILE_EXTENTS returns - serial number %08lX flags %lX FileCount %lX",
1656                       responseBuffer->SerialNumber, responseBuffer->Flags, responseBuffer->FileCount);
1657             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1658         }
1659
1660         rc = RDR_ProcessReleaseFileExtentsResult( responseBuffer, bytesReturned);
1661     } else {
1662
1663         rc = ENOMEM;
1664     }
1665
1666   cleanup:
1667     if (requestBuffer)
1668         free( requestBuffer);
1669     if (responseBuffer)
1670         free( responseBuffer);
1671
1672     return rc;
1673 }
1674
1675
1676 extern "C" DWORD
1677 RDR_NetworkStatus(BOOLEAN status)
1678 {
1679
1680     HANDLE hDevHandle = NULL;
1681     DWORD bytesReturned;
1682     AFSNetworkStatusCB *requestBuffer = NULL;
1683     DWORD rc = 0;
1684     WCHAR wchBuffer[256];
1685     DWORD gle;
1686
1687     if (afsd_logp->enabled) {
1688         swprintf( wchBuffer,
1689                   L"IOCTL_AFS_NETWORK_STATUS request - status %d",
1690                   status);
1691
1692         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1693     }
1694
1695     //
1696     // We use the global handle to the control device instance
1697     //
1698
1699     hDevHandle = glDevHandle;
1700
1701     //
1702     // Allocate a request buffer.
1703     //
1704
1705     requestBuffer = (AFSNetworkStatusCB *)malloc( sizeof( AFSNetworkStatusCB));
1706
1707
1708     if( requestBuffer)
1709     {
1710
1711         memset( requestBuffer, '\0', sizeof( AFSNetworkStatusCB));
1712
1713         // Set the number of extents to be freed
1714         // Leave the rest of the structure as zeros to indicate free anything
1715         requestBuffer->Online = status;
1716
1717         if( !RDR_DeviceIoControl( hDevHandle,
1718                                   IOCTL_AFS_NETWORK_STATUS,
1719                                   (void *)requestBuffer,
1720                                   sizeof( AFSNetworkStatusCB),
1721                                   NULL,
1722                                   0,
1723                                   &bytesReturned ))
1724         {
1725             //
1726             // Error condition back from driver
1727             //
1728             if (afsd_logp->enabled) {
1729                 gle = GetLastError();
1730                 swprintf( wchBuffer,
1731                           L"Failed to post IOCTL_AFS_NETWORK_STATUS gle 0x%x",
1732                           gle);
1733                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1734             }
1735
1736             rc = -1;
1737             goto cleanup;
1738         }
1739     } else
1740         rc = ENOMEM;
1741
1742   cleanup:
1743     if (requestBuffer)
1744         free( requestBuffer);
1745
1746     return rc;
1747 }
1748
1749
1750
1751 extern "C" DWORD
1752 RDR_VolumeStatus(ULONG cellID, ULONG volID, BOOLEAN online)
1753 {
1754
1755     HANDLE hDevHandle = NULL;
1756     DWORD bytesReturned;
1757     AFSVolumeStatusCB *requestBuffer = NULL;
1758     DWORD rc = 0;
1759     WCHAR wchBuffer[256];
1760     DWORD gle;
1761
1762     if (afsd_logp->enabled) {
1763         swprintf( wchBuffer,
1764                   L"IOCTL_AFS_VOLUME_STATUS request - cell 0x%x vol 0x%x online %d",
1765                   cellID, volID, online);
1766
1767         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1768     }
1769
1770     //
1771     // We use the global handle to the control device instance
1772     //
1773
1774     hDevHandle = glDevHandle;
1775
1776     //
1777     // Allocate a request buffer.
1778     //
1779
1780     requestBuffer = (AFSVolumeStatusCB *)malloc( sizeof( AFSVolumeStatusCB));
1781
1782
1783     if( requestBuffer)
1784     {
1785
1786         memset( requestBuffer, '\0', sizeof( AFSVolumeStatusCB));
1787
1788         requestBuffer->FileID.Cell = cellID;
1789         requestBuffer->FileID.Volume = volID;
1790         requestBuffer->Online = online;
1791
1792         if( !RDR_DeviceIoControl( hDevHandle,
1793                                   IOCTL_AFS_VOLUME_STATUS,
1794                                   (void *)requestBuffer,
1795                                   sizeof( AFSVolumeStatusCB),
1796                                   NULL,
1797                                   0,
1798                                   &bytesReturned ))
1799         {
1800             //
1801             // Error condition back from driver
1802             //
1803
1804             if (afsd_logp->enabled) {
1805                 gle = GetLastError();
1806                 swprintf( wchBuffer,
1807                           L"Failed to post IOCTL_AFS_VOLUME_STATUS gle 0x%x", gle);
1808                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1809             }
1810
1811             rc = -1;
1812             goto cleanup;
1813         }
1814     } else
1815         rc = ENOMEM;
1816
1817   cleanup:
1818     if (requestBuffer)
1819         free( requestBuffer);
1820
1821     return rc;
1822 }
1823
1824 extern "C" DWORD
1825 RDR_NetworkAddrChange(void)
1826 {
1827     return 0;
1828 }
1829
1830
1831 extern "C" DWORD
1832 RDR_InvalidateVolume(ULONG cellID, ULONG volID, ULONG reason)
1833 {
1834
1835     HANDLE hDevHandle = NULL;
1836     DWORD bytesReturned;
1837     AFSInvalidateCacheCB *requestBuffer = NULL;
1838     DWORD rc = 0;
1839     WCHAR wchBuffer[256];
1840     DWORD gle;
1841
1842     if (afsd_logp->enabled) {
1843         swprintf( wchBuffer,
1844                   L"IOCTL_AFS_INVALIDATE_CACHE (vol) request - cell 0x%x vol 0x%x reason %d",
1845                   cellID, volID, reason);
1846
1847         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1848     }
1849
1850     //
1851     // We use the global handle to the control device instance
1852     //
1853
1854     hDevHandle = glDevHandle;
1855
1856     //
1857     // Allocate a request buffer.
1858     //
1859
1860     requestBuffer = (AFSInvalidateCacheCB *)malloc( sizeof( AFSInvalidateCacheCB));
1861
1862
1863     if( requestBuffer)
1864     {
1865
1866         memset( requestBuffer, '\0', sizeof( AFSInvalidateCacheCB));
1867
1868         requestBuffer->FileID.Cell = cellID;
1869         requestBuffer->FileID.Volume = volID;
1870         requestBuffer->WholeVolume = TRUE;
1871         requestBuffer->Reason = reason;
1872
1873         if( !RDR_DeviceIoControl( hDevHandle,
1874                                   IOCTL_AFS_INVALIDATE_CACHE,
1875                                   (void *)requestBuffer,
1876                                   sizeof( AFSInvalidateCacheCB),
1877                                   NULL,
1878                                   0,
1879                                   &bytesReturned ))
1880         {
1881             //
1882             // Error condition back from driver
1883             //
1884
1885             if (afsd_logp->enabled) {
1886                 gle = GetLastError();
1887                 swprintf( wchBuffer,
1888                           L"Failed to post IOCTL_AFS_INVALIDATE_VOLUME gle 0x%x", gle);
1889                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1890             }
1891
1892             rc = -1;
1893             goto cleanup;
1894         }
1895     } else
1896         rc = ENOMEM;
1897
1898   cleanup:
1899     if (requestBuffer)
1900         free( requestBuffer);
1901
1902     return rc;
1903 }
1904
1905
1906 extern "C" DWORD
1907 RDR_InvalidateObject(ULONG cellID, ULONG volID, ULONG vnode, ULONG uniq, ULONG hash, ULONG fileType, ULONG reason)
1908 {
1909
1910     HANDLE hDevHandle = NULL;
1911     DWORD bytesReturned;
1912     AFSInvalidateCacheCB *requestBuffer = NULL;
1913     DWORD rc = 0;
1914     WCHAR wchBuffer[256];
1915     DWORD gle;
1916
1917     if (afsd_logp->enabled) {
1918         swprintf( wchBuffer,
1919                   L"IOCTL_AFS_INVALIDATE_CACHE (obj) request - cell 0x%x vol 0x%x vn 0x%x uniq 0x%x hash 0x%x type 0x%x reason %d",
1920                   cellID, volID, vnode, uniq, hash, fileType, reason);
1921
1922         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1923     }
1924
1925     //
1926     // We use the global handle to the control device instance
1927     //
1928
1929     hDevHandle = glDevHandle;
1930
1931     //
1932     // Allocate a request buffer.
1933     //
1934
1935     requestBuffer = (AFSInvalidateCacheCB *)malloc( sizeof( AFSInvalidateCacheCB));
1936
1937
1938     if( requestBuffer)
1939     {
1940
1941         memset( requestBuffer, '\0', sizeof( AFSInvalidateCacheCB));
1942
1943         requestBuffer->FileID.Cell = cellID;
1944         requestBuffer->FileID.Volume = volID;
1945         requestBuffer->FileID.Vnode = vnode;
1946         requestBuffer->FileID.Unique = uniq;
1947         requestBuffer->FileID.Hash = hash;
1948         requestBuffer->FileType = fileType;
1949         requestBuffer->WholeVolume = FALSE;
1950         requestBuffer->Reason = reason;
1951
1952         if( !RDR_DeviceIoControl( hDevHandle,
1953                                   IOCTL_AFS_INVALIDATE_CACHE,
1954                                   (void *)requestBuffer,
1955                                   sizeof( AFSInvalidateCacheCB),
1956                                   NULL,
1957                                   0,
1958                                   &bytesReturned ))
1959         {
1960             //
1961             // Error condition back from driver
1962             //
1963             if (afsd_logp->enabled) {
1964                 gle = GetLastError();
1965                 swprintf( wchBuffer,
1966                           L"Failed to post IOCTL_AFS_INVALIDATE_CACHE gle 0x%x", gle);
1967                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1968             }
1969
1970             rc = -1;
1971             goto cleanup;
1972         }
1973     } else
1974         rc = ENOMEM;
1975
1976   cleanup:
1977     if (requestBuffer)
1978         free( requestBuffer);
1979
1980     return rc;
1981 }
1982
1983
1984
1985 extern "C" DWORD
1986 RDR_SysName(ULONG Architecture, ULONG Count, WCHAR **NameList)
1987 {
1988
1989     HANDLE hDevHandle = NULL;
1990     DWORD bytesReturned;
1991     AFSSysNameNotificationCB *requestBuffer = NULL;
1992     DWORD rc = 0;
1993     WCHAR wchBuffer[256];
1994     DWORD Length;
1995     DWORD gle;
1996
1997     if (afsd_logp->enabled) {
1998         swprintf( wchBuffer,
1999                   L"IOCTL_AFS_SYSNAME_NOTIFICATION request - Arch %d Count %d",
2000                   Architecture, Count);
2001
2002         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
2003     }
2004
2005     if (Count <= 0 || NameList == NULL)
2006         return -1;
2007
2008     //
2009     // We use the global handle to the control device instance
2010     //
2011
2012     hDevHandle = glDevHandle;
2013
2014     //
2015     // Allocate a request buffer.
2016     //
2017
2018     Length = sizeof (AFSSysNameNotificationCB) + (Count - 1) * sizeof (AFSSysName);
2019     requestBuffer = (AFSSysNameNotificationCB *)malloc( Length );
2020
2021
2022     if( requestBuffer)
2023     {
2024         unsigned int i;
2025
2026         memset( requestBuffer, '\0', Length);
2027
2028         requestBuffer->Architecture = Architecture;
2029         requestBuffer->NumberOfNames = Count;
2030         for ( i=0 ; i<Count; i++) {
2031             size_t len = wcslen(NameList[i]);
2032             requestBuffer->SysNames[i].Length = (ULONG) (len * sizeof(WCHAR));
2033             StringCchCopyNW(requestBuffer->SysNames[i].String, AFS_MAX_SYSNAME_LENGTH,
2034                             NameList[i], len);
2035         }
2036
2037         if( !RDR_DeviceIoControl( hDevHandle,
2038                                   IOCTL_AFS_SYSNAME_NOTIFICATION,
2039                                   (void *)requestBuffer,
2040                                   Length,
2041                                   NULL,
2042                                   0,
2043                                   &bytesReturned ))
2044         {
2045             //
2046             // Error condition back from driver
2047             //
2048             if (afsd_logp->enabled) {
2049                 gle = GetLastError();
2050                 swprintf( wchBuffer,
2051                           L"Failed to post IOCTL_AFS_SYSNAME_NOTIFICATION gle 0x%x", gle);
2052                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
2053             }
2054
2055             rc = -1;
2056             goto cleanup;
2057         }
2058     } else
2059         rc = ENOMEM;
2060
2061   cleanup:
2062     if (requestBuffer)
2063         free( requestBuffer);
2064
2065     return rc;
2066 }
2067
2068 extern "C" VOID
2069 RDR_Suspend( VOID)
2070 {
2071     ResetEvent( RDR_SuspendEvent);
2072 }
2073
2074 extern "C" VOID
2075 RDR_Resume( VOID)
2076 {
2077     SetEvent( RDR_SuspendEvent);
2078 }