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