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