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