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