371f4658ce30951ed3d5f910331762d644e28f28
[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
1524     RDR_fid2FID(fidp, &SetFileStatusCB.FileId);
1525     SetFileStatusCB.FailureStatus = dwStatus;
1526
1527     if (afsd_logp->enabled) {
1528         swprintf( wchBuffer, L"RDR_SetFileStatus IOCTL_AFS_EXTENT_FAILURE_CB Fid %08lX.%08lX.%08lX.%08lX Status 0x%lX",
1529                   SetFileStatusCB.FileId.Cell, SetFileStatusCB.FileId.Volume,
1530                   SetFileStatusCB.FileId.Vnode, SetFileStatusCB.FileId.Unique,
1531                   dwStatus);
1532
1533         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1534     }
1535
1536     if( !RDR_DeviceIoControl( glDevHandle,
1537                               IOCTL_AFS_SET_FILE_EXTENT_FAILURE,
1538                               (void *)&SetFileStatusCB,
1539                               sizeof(AFSExtentFailureCB),
1540                               (void *)NULL,
1541                               0,
1542                               &bytesReturned ))
1543     {
1544         gle = GetLastError();
1545         return gle;
1546     }
1547
1548     return 0;
1549 }
1550
1551
1552 extern "C" DWORD
1553 RDR_RequestExtentRelease(cm_fid_t *fidp, LARGE_INTEGER numOfHeldExtents, DWORD numOfExtents, AFSFileExtentCB *extentList)
1554 {
1555
1556     HANDLE hDevHandle = NULL;
1557     DWORD bytesReturned;
1558     AFSReleaseFileExtentsCB *requestBuffer = NULL;
1559     AFSReleaseFileExtentsResultCB *responseBuffer = NULL;
1560     DWORD requestBufferLen, responseBufferLen;
1561     bool bError = false;
1562     DWORD rc = 0;
1563     WCHAR wchBuffer[256];
1564     DWORD gle;
1565
1566     if (ExitPending) {
1567         if (afsd_logp->enabled) {
1568             swprintf( wchBuffer,
1569                       L"IOCTL_AFS_RELEASE_FILE_EXTENTS request ignored due to shutdown pending");
1570
1571             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1572         }
1573
1574         OutputDebugString(L"RDR_RequestExtentRequest ignored - shutdown pending\n");
1575         return CM_ERROR_WOULDBLOCK;
1576     }
1577
1578     if (afsd_logp->enabled) {
1579         swprintf( wchBuffer,
1580                   L"IOCTL_AFS_RELEASE_FILE_EXTENTS request - number %08lX",
1581                   numOfExtents);
1582
1583         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1584     }
1585
1586     //
1587     // We use the global handle to the control device instance
1588     //
1589
1590     hDevHandle = glDevHandle;
1591
1592     //
1593     // Allocate a request buffer.
1594     //
1595
1596     requestBufferLen = sizeof( AFSReleaseFileExtentsCB) + sizeof(AFSFileExtentCB) * numOfExtents;
1597     requestBuffer = (AFSReleaseFileExtentsCB *)malloc( requestBufferLen);
1598     responseBufferLen = (sizeof( AFSReleaseFileExtentsResultCB) + sizeof( AFSReleaseFileExtentsResultFileCB)) * numOfExtents;
1599     responseBuffer = (AFSReleaseFileExtentsResultCB *)malloc( responseBufferLen);
1600
1601
1602     if( requestBuffer && responseBuffer)
1603     {
1604
1605         memset( requestBuffer, '\0', sizeof( AFSReleaseFileExtentsCB));
1606         memset( responseBuffer, '\0', responseBufferLen);
1607
1608         // If there is a FID provided, use it
1609         if (fidp && extentList)
1610         {
1611             RDR_fid2FID( fidp, &requestBuffer->FileId);
1612
1613             memcpy(&requestBuffer->FileExtents, extentList, numOfExtents * sizeof(AFSFileExtentCB));
1614
1615             requestBuffer->Flags = 0;
1616         } else {
1617
1618             requestBuffer->Flags = AFS_RELEASE_EXTENTS_FLAGS_RELEASE_ALL;
1619         }
1620
1621         // Set the number of extents to be freed
1622         // Leave the rest of the structure as zeros to indicate free anything
1623         requestBuffer->ExtentCount = numOfExtents;
1624
1625         requestBuffer->HeldExtentCount = numOfHeldExtents;
1626
1627         if( !RDR_DeviceIoControl( hDevHandle,
1628                                   IOCTL_AFS_RELEASE_FILE_EXTENTS,
1629                                   (void *)requestBuffer,
1630                                   requestBufferLen,
1631                                   (void *)responseBuffer,
1632                                   responseBufferLen,
1633                                   &bytesReturned ))
1634         {
1635             //
1636             // Error condition back from driver
1637             //
1638             if (afsd_logp->enabled) {
1639                 gle = GetLastError();
1640                 swprintf( wchBuffer,
1641                           L"Failed to post IOCTL_AFS_RELEASE_FILE_EXTENTS - gle 0x%x", gle);
1642                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1643             }
1644             rc = -1;
1645             goto cleanup;
1646         }
1647
1648         //
1649         // Go process the request
1650         //
1651
1652         if (afsd_logp->enabled) {
1653             swprintf( wchBuffer,
1654                       L"IOCTL_AFS_RELEASE_FILE_EXTENTS returns - serial number %08lX flags %lX FileCount %lX",
1655                       responseBuffer->SerialNumber, responseBuffer->Flags, responseBuffer->FileCount);
1656             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1657         }
1658
1659         rc = RDR_ProcessReleaseFileExtentsResult( responseBuffer, bytesReturned);
1660     } else {
1661
1662         rc = ENOMEM;
1663     }
1664
1665   cleanup:
1666     if (requestBuffer)
1667         free( requestBuffer);
1668     if (responseBuffer)
1669         free( responseBuffer);
1670
1671     return rc;
1672 }
1673
1674
1675 extern "C" DWORD
1676 RDR_NetworkStatus(BOOLEAN status)
1677 {
1678
1679     HANDLE hDevHandle = NULL;
1680     DWORD bytesReturned;
1681     AFSNetworkStatusCB *requestBuffer = NULL;
1682     DWORD rc = 0;
1683     WCHAR wchBuffer[256];
1684     DWORD gle;
1685
1686     if (afsd_logp->enabled) {
1687         swprintf( wchBuffer,
1688                   L"IOCTL_AFS_NETWORK_STATUS request - status %d",
1689                   status);
1690
1691         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1692     }
1693
1694     //
1695     // We use the global handle to the control device instance
1696     //
1697
1698     hDevHandle = glDevHandle;
1699
1700     //
1701     // Allocate a request buffer.
1702     //
1703
1704     requestBuffer = (AFSNetworkStatusCB *)malloc( sizeof( AFSNetworkStatusCB));
1705
1706
1707     if( requestBuffer)
1708     {
1709
1710         memset( requestBuffer, '\0', sizeof( AFSNetworkStatusCB));
1711
1712         // Set the number of extents to be freed
1713         // Leave the rest of the structure as zeros to indicate free anything
1714         requestBuffer->Online = status;
1715
1716         if( !RDR_DeviceIoControl( hDevHandle,
1717                                   IOCTL_AFS_NETWORK_STATUS,
1718                                   (void *)requestBuffer,
1719                                   sizeof( AFSNetworkStatusCB),
1720                                   NULL,
1721                                   0,
1722                                   &bytesReturned ))
1723         {
1724             //
1725             // Error condition back from driver
1726             //
1727             if (afsd_logp->enabled) {
1728                 gle = GetLastError();
1729                 swprintf( wchBuffer,
1730                           L"Failed to post IOCTL_AFS_NETWORK_STATUS gle 0x%x",
1731                           gle);
1732                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1733             }
1734
1735             rc = -1;
1736             goto cleanup;
1737         }
1738     } else
1739         rc = ENOMEM;
1740
1741   cleanup:
1742     if (requestBuffer)
1743         free( requestBuffer);
1744
1745     return rc;
1746 }
1747
1748
1749
1750 extern "C" DWORD
1751 RDR_VolumeStatus(ULONG cellID, ULONG volID, BOOLEAN online)
1752 {
1753
1754     HANDLE hDevHandle = NULL;
1755     DWORD bytesReturned;
1756     AFSVolumeStatusCB *requestBuffer = NULL;
1757     DWORD rc = 0;
1758     WCHAR wchBuffer[256];
1759     DWORD gle;
1760
1761     if (afsd_logp->enabled) {
1762         swprintf( wchBuffer,
1763                   L"IOCTL_AFS_VOLUME_STATUS request - cell 0x%x vol 0x%x online %d",
1764                   cellID, volID, online);
1765
1766         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1767     }
1768
1769     //
1770     // We use the global handle to the control device instance
1771     //
1772
1773     hDevHandle = glDevHandle;
1774
1775     //
1776     // Allocate a request buffer.
1777     //
1778
1779     requestBuffer = (AFSVolumeStatusCB *)malloc( sizeof( AFSVolumeStatusCB));
1780
1781
1782     if( requestBuffer)
1783     {
1784
1785         memset( requestBuffer, '\0', sizeof( AFSVolumeStatusCB));
1786
1787         requestBuffer->FileID.Cell = cellID;
1788         requestBuffer->FileID.Volume = volID;
1789         requestBuffer->Online = online;
1790
1791         if( !RDR_DeviceIoControl( hDevHandle,
1792                                   IOCTL_AFS_VOLUME_STATUS,
1793                                   (void *)requestBuffer,
1794                                   sizeof( AFSVolumeStatusCB),
1795                                   NULL,
1796                                   0,
1797                                   &bytesReturned ))
1798         {
1799             //
1800             // Error condition back from driver
1801             //
1802
1803             if (afsd_logp->enabled) {
1804                 gle = GetLastError();
1805                 swprintf( wchBuffer,
1806                           L"Failed to post IOCTL_AFS_VOLUME_STATUS gle 0x%x", gle);
1807                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1808             }
1809
1810             rc = -1;
1811             goto cleanup;
1812         }
1813     } else
1814         rc = ENOMEM;
1815
1816   cleanup:
1817     if (requestBuffer)
1818         free( requestBuffer);
1819
1820     return rc;
1821 }
1822
1823 extern "C" DWORD
1824 RDR_NetworkAddrChange(void)
1825 {
1826     return 0;
1827 }
1828
1829
1830 extern "C" DWORD
1831 RDR_InvalidateVolume(ULONG cellID, ULONG volID, ULONG reason)
1832 {
1833
1834     HANDLE hDevHandle = NULL;
1835     DWORD bytesReturned;
1836     AFSInvalidateCacheCB *requestBuffer = NULL;
1837     DWORD rc = 0;
1838     WCHAR wchBuffer[256];
1839     DWORD gle;
1840
1841     if (afsd_logp->enabled) {
1842         swprintf( wchBuffer,
1843                   L"IOCTL_AFS_INVALIDATE_CACHE (vol) request - cell 0x%x vol 0x%x reason %d",
1844                   cellID, volID, reason);
1845
1846         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1847     }
1848
1849     //
1850     // We use the global handle to the control device instance
1851     //
1852
1853     hDevHandle = glDevHandle;
1854
1855     //
1856     // Allocate a request buffer.
1857     //
1858
1859     requestBuffer = (AFSInvalidateCacheCB *)malloc( sizeof( AFSInvalidateCacheCB));
1860
1861
1862     if( requestBuffer)
1863     {
1864
1865         memset( requestBuffer, '\0', sizeof( AFSInvalidateCacheCB));
1866
1867         requestBuffer->FileID.Cell = cellID;
1868         requestBuffer->FileID.Volume = volID;
1869         requestBuffer->WholeVolume = TRUE;
1870         requestBuffer->Reason = reason;
1871
1872         if( !RDR_DeviceIoControl( hDevHandle,
1873                                   IOCTL_AFS_INVALIDATE_CACHE,
1874                                   (void *)requestBuffer,
1875                                   sizeof( AFSInvalidateCacheCB),
1876                                   NULL,
1877                                   0,
1878                                   &bytesReturned ))
1879         {
1880             //
1881             // Error condition back from driver
1882             //
1883
1884             if (afsd_logp->enabled) {
1885                 gle = GetLastError();
1886                 swprintf( wchBuffer,
1887                           L"Failed to post IOCTL_AFS_INVALIDATE_VOLUME gle 0x%x", gle);
1888                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1889             }
1890
1891             rc = -1;
1892             goto cleanup;
1893         }
1894     } else
1895         rc = ENOMEM;
1896
1897   cleanup:
1898     if (requestBuffer)
1899         free( requestBuffer);
1900
1901     return rc;
1902 }
1903
1904
1905 extern "C" DWORD
1906 RDR_InvalidateObject(ULONG cellID, ULONG volID, ULONG vnode, ULONG uniq, ULONG hash, ULONG fileType, ULONG reason)
1907 {
1908
1909     HANDLE hDevHandle = NULL;
1910     DWORD bytesReturned;
1911     AFSInvalidateCacheCB *requestBuffer = NULL;
1912     DWORD rc = 0;
1913     WCHAR wchBuffer[256];
1914     DWORD gle;
1915
1916     if (afsd_logp->enabled) {
1917         swprintf( wchBuffer,
1918                   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",
1919                   cellID, volID, vnode, uniq, hash, fileType, reason);
1920
1921         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1922     }
1923
1924     //
1925     // We use the global handle to the control device instance
1926     //
1927
1928     hDevHandle = glDevHandle;
1929
1930     //
1931     // Allocate a request buffer.
1932     //
1933
1934     requestBuffer = (AFSInvalidateCacheCB *)malloc( sizeof( AFSInvalidateCacheCB));
1935
1936
1937     if( requestBuffer)
1938     {
1939
1940         memset( requestBuffer, '\0', sizeof( AFSInvalidateCacheCB));
1941
1942         requestBuffer->FileID.Cell = cellID;
1943         requestBuffer->FileID.Volume = volID;
1944         requestBuffer->FileID.Vnode = vnode;
1945         requestBuffer->FileID.Unique = uniq;
1946         requestBuffer->FileID.Hash = hash;
1947         requestBuffer->FileType = fileType;
1948         requestBuffer->WholeVolume = FALSE;
1949         requestBuffer->Reason = reason;
1950
1951         if( !RDR_DeviceIoControl( hDevHandle,
1952                                   IOCTL_AFS_INVALIDATE_CACHE,
1953                                   (void *)requestBuffer,
1954                                   sizeof( AFSInvalidateCacheCB),
1955                                   NULL,
1956                                   0,
1957                                   &bytesReturned ))
1958         {
1959             //
1960             // Error condition back from driver
1961             //
1962             if (afsd_logp->enabled) {
1963                 gle = GetLastError();
1964                 swprintf( wchBuffer,
1965                           L"Failed to post IOCTL_AFS_INVALIDATE_CACHE gle 0x%x", gle);
1966                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1967             }
1968
1969             rc = -1;
1970             goto cleanup;
1971         }
1972     } else
1973         rc = ENOMEM;
1974
1975   cleanup:
1976     if (requestBuffer)
1977         free( requestBuffer);
1978
1979     return rc;
1980 }
1981
1982
1983
1984 extern "C" DWORD
1985 RDR_SysName(ULONG Architecture, ULONG Count, WCHAR **NameList)
1986 {
1987
1988     HANDLE hDevHandle = NULL;
1989     DWORD bytesReturned;
1990     AFSSysNameNotificationCB *requestBuffer = NULL;
1991     DWORD rc = 0;
1992     WCHAR wchBuffer[256];
1993     DWORD Length;
1994     DWORD gle;
1995
1996     if (afsd_logp->enabled) {
1997         swprintf( wchBuffer,
1998                   L"IOCTL_AFS_SYSNAME_NOTIFICATION request - Arch %d Count %d",
1999                   Architecture, Count);
2000
2001         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
2002     }
2003
2004     if (Count <= 0 || NameList == NULL)
2005         return -1;
2006
2007     //
2008     // We use the global handle to the control device instance
2009     //
2010
2011     hDevHandle = glDevHandle;
2012
2013     //
2014     // Allocate a request buffer.
2015     //
2016
2017     Length = sizeof (AFSSysNameNotificationCB) + (Count - 1) * sizeof (AFSSysName);
2018     requestBuffer = (AFSSysNameNotificationCB *)malloc( Length );
2019
2020
2021     if( requestBuffer)
2022     {
2023         unsigned int i;
2024
2025         memset( requestBuffer, '\0', Length);
2026
2027         requestBuffer->Architecture = Architecture;
2028         requestBuffer->NumberOfNames = Count;
2029         for ( i=0 ; i<Count; i++) {
2030             size_t len = wcslen(NameList[i]);
2031             requestBuffer->SysNames[i].Length = (ULONG) (len * sizeof(WCHAR));
2032             StringCchCopyNW(requestBuffer->SysNames[i].String, AFS_MAX_SYSNAME_LENGTH,
2033                             NameList[i], len);
2034         }
2035
2036         if( !RDR_DeviceIoControl( hDevHandle,
2037                                   IOCTL_AFS_SYSNAME_NOTIFICATION,
2038                                   (void *)requestBuffer,
2039                                   Length,
2040                                   NULL,
2041                                   0,
2042                                   &bytesReturned ))
2043         {
2044             //
2045             // Error condition back from driver
2046             //
2047             if (afsd_logp->enabled) {
2048                 gle = GetLastError();
2049                 swprintf( wchBuffer,
2050                           L"Failed to post IOCTL_AFS_SYSNAME_NOTIFICATION gle 0x%x", gle);
2051                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
2052             }
2053
2054             rc = -1;
2055             goto cleanup;
2056         }
2057     } else
2058         rc = ENOMEM;
2059
2060   cleanup:
2061     if (requestBuffer)
2062         free( requestBuffer);
2063
2064     return rc;
2065 }
2066
2067 extern "C" VOID
2068 RDR_Suspend( VOID)
2069 {
2070     ResetEvent( RDR_SuspendEvent);
2071 }
2072
2073 extern "C" VOID
2074 RDR_Resume( VOID)
2075 {
2076     SetEvent( RDR_SuspendEvent);
2077 }