d481a781e58a7332642dd1921d6f3008ad588a7a
[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 TargetLength %08lX Target %*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                           pFileRenameCB->TargetNameLength, (int)pFileRenameCB->TargetNameLength, pFileRenameCB->TargetName);
726
727                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
728             }
729
730             RDR_RenameFileEntry( userp,
731                                  RequestBuffer->Name,
732                                  RequestBuffer->NameLength,
733                                  RequestBuffer->FileId,
734                                  pFileRenameCB,
735                                  bWow64,
736                                  RequestBuffer->ResultBufferLength,
737                                  &pResultCB);
738
739             break;
740         }
741
742         case AFS_REQUEST_TYPE_HARDLINK_FILE:
743         {
744
745             AFSFileHardLinkCB *pFileHardLinkCB = (AFSFileHardLinkCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
746
747             if (afsd_logp->enabled) {
748                 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",
749                           RequestBuffer->RequestIndex,
750                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
751                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
752                           RequestBuffer->NameLength, (int)RequestBuffer->NameLength, RequestBuffer->Name,
753                           pFileHardLinkCB->TargetNameLength, (int)pFileHardLinkCB->TargetNameLength, pFileHardLinkCB->TargetName);
754
755                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
756                 }
757
758                 RDR_HardLinkFileEntry( userp,
759                                        RequestBuffer->Name,
760                                        RequestBuffer->NameLength,
761                                        RequestBuffer->FileId,
762                                        pFileHardLinkCB,
763                                        bWow64,
764                                        RequestBuffer->ResultBufferLength,
765                                        &pResultCB);
766
767             break;
768         }
769
770         case AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS:
771         {
772
773             AFSRequestExtentsCB *pFileRequestExtentsCB = (AFSRequestExtentsCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
774
775             if (afsd_logp->enabled) {
776                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS Index %08lX File %08lX.%08lX.%08lX.%08lX %S",
777                           RequestBuffer->RequestIndex,
778                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
779                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
780                           BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS) ? L"Sync" : L"Async");
781
782                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
783             }
784
785             if (BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS))
786                 osi_panic("SYNCHRONOUS AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS not supported",
787                           __FILE__, __LINE__);
788             else
789                 bRetry = RDR_RequestFileExtentsAsync( userp, RequestBuffer->FileId,
790                                                       pFileRequestExtentsCB,
791                                                       bWow64,
792                                                       &dwResultBufferLength,
793                                                       &SetFileExtentsResultCB );
794             break;
795         }
796
797         case AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS:
798         {
799
800             AFSReleaseExtentsCB *pFileReleaseExtentsCB = (AFSReleaseExtentsCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
801
802             if (afsd_logp->enabled) {
803                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS Index %08lX File %08lX.%08lX.%08lX.%08lX",
804                           RequestBuffer->RequestIndex,
805                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
806                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
807
808                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
809             }
810
811             RDR_ReleaseFileExtents( userp, RequestBuffer->FileId,
812                                     pFileReleaseExtentsCB,
813                                     bWow64,
814                                     RequestBuffer->ResultBufferLength,
815                                     &pResultCB);
816
817             break;
818         }
819
820         case AFS_REQUEST_TYPE_FLUSH_FILE:
821         {
822             if (afsd_logp->enabled) {
823                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_FLUSH_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
824                           RequestBuffer->RequestIndex,
825                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
826                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
827
828                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
829             }
830
831             RDR_FlushFileEntry( userp, RequestBuffer->FileId,
832                                 bWow64,
833                                 RequestBuffer->ResultBufferLength,
834                                 &pResultCB);
835             break;
836         }
837
838         case AFS_REQUEST_TYPE_OPEN_FILE:
839         {
840             AFSFileOpenCB *pFileOpenCB = (AFSFileOpenCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
841
842             if (afsd_logp->enabled) {
843                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_OPEN_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
844                           RequestBuffer->RequestIndex,
845                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
846                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
847
848                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
849             }
850
851             RDR_OpenFileEntry( userp, RequestBuffer->FileId,
852                                pFileOpenCB,
853                                bWow64,
854                                bHoldFid,
855                                RequestBuffer->ResultBufferLength,
856                                &pResultCB);
857
858             break;
859         }
860
861         case AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS:
862         {
863             AFSFileAccessReleaseCB *pFileAccessReleaseCB = (AFSFileAccessReleaseCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
864
865             if (afsd_logp->enabled) {
866                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_RELEASE_FILE_ACCESS Index %08lX File %08lX.%08lX.%08lX.%08lX",
867                           RequestBuffer->RequestIndex,
868                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
869                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
870
871                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
872             }
873
874             RDR_ReleaseFileAccess( userp,
875                                    RequestBuffer->FileId,
876                                    pFileAccessReleaseCB,
877                                    bWow64,
878                                    RequestBuffer->ResultBufferLength,
879                                    &pResultCB);
880
881             break;
882         }
883
884         case AFS_REQUEST_TYPE_PIOCTL_OPEN:
885         {
886             AFSPIOCtlOpenCloseRequestCB *pPioctlCB = (AFSPIOCtlOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
887
888             if (afsd_logp->enabled) {
889                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_OPEN Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
890                           RequestBuffer->RequestIndex,
891                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
892                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
893
894                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
895             }
896
897             RDR_PioctlOpen( userp,
898                             RequestBuffer->FileId,
899                             pPioctlCB,
900                             bWow64,
901                             RequestBuffer->ResultBufferLength,
902                             &pResultCB);
903             break;
904         }
905
906         case AFS_REQUEST_TYPE_PIOCTL_WRITE:
907         {
908             AFSPIOCtlIORequestCB *pPioctlCB = (AFSPIOCtlIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
909
910             if (afsd_logp->enabled) {
911                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_WRITE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
912                           RequestBuffer->RequestIndex,
913                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
914                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
915
916                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
917             }
918
919             RDR_PioctlWrite( userp,
920                              RequestBuffer->FileId,
921                              pPioctlCB,
922                              bWow64,
923                              RequestBuffer->ResultBufferLength,
924                              &pResultCB);
925             break;
926         }
927
928         case AFS_REQUEST_TYPE_PIOCTL_READ:
929         {
930             AFSPIOCtlIORequestCB *pPioctlCB = (AFSPIOCtlIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
931
932             if (afsd_logp->enabled) {
933                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_READ Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
934                           RequestBuffer->RequestIndex,
935                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
936                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
937
938                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
939             }
940
941             RDR_PioctlRead( userp,
942                             RequestBuffer->FileId,
943                             pPioctlCB,
944                             bWow64,
945                             bIsLocalSystem,
946                             RequestBuffer->ResultBufferLength,
947                             &pResultCB);
948             break;
949         }
950
951         case AFS_REQUEST_TYPE_PIOCTL_CLOSE:
952         {
953             AFSPIOCtlOpenCloseRequestCB *pPioctlCB = (AFSPIOCtlOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
954
955             if (afsd_logp->enabled) {
956                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIOCTL_CLOSE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
957                           RequestBuffer->RequestIndex,
958                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
959                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
960
961                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
962             }
963
964             RDR_PioctlClose( userp,
965                              RequestBuffer->FileId,
966                              pPioctlCB,
967                              bWow64,
968                              RequestBuffer->ResultBufferLength,
969                              &pResultCB);
970             break;
971         }
972
973
974         case AFS_REQUEST_TYPE_BYTE_RANGE_LOCK:
975         {
976             if (afsd_logp->enabled) {
977                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_BYTE_RANGE_LOCK Index %08lX File %08lX.%08lX.%08lX.%08lX %S",
978                           RequestBuffer->RequestIndex,
979                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
980                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique,
981                           BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS) ? L"Sync" : L"Async");
982
983                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
984             }
985
986             AFSByteRangeLockRequestCB *pBRLRequestCB = (AFSByteRangeLockRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
987
988             RDR_ByteRangeLockSync( userp,
989                                    RequestBuffer->FileId,
990                                    pBRLRequestCB,
991                                    bWow64,
992                                    RequestBuffer->ResultBufferLength,
993                                    &pResultCB);
994
995             break;
996         }
997
998         case AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK:
999         {
1000             AFSByteRangeUnlockRequestCB *pBRURequestCB = (AFSByteRangeUnlockRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1001
1002             if (afsd_logp->enabled) {
1003                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK Index %08lX File %08lX.%08lX.%08lX.%08lX",
1004                           RequestBuffer->RequestIndex,
1005                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1006                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1007
1008                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1009             }
1010
1011             RDR_ByteRangeUnlock( userp,
1012                                  RequestBuffer->FileId,
1013                                  pBRURequestCB,
1014                                  bWow64,
1015                                  RequestBuffer->ResultBufferLength,
1016                                  &pResultCB);
1017             break;
1018         }
1019
1020         case AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK_ALL:
1021         {
1022             AFSByteRangeUnlockRequestCB *pBRURequestCB = (AFSByteRangeUnlockRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1023
1024             if (afsd_logp->enabled) {
1025                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_BYTE_RANGE_UNLOCK_ALL Index %08lX File %08lX.%08lX.%08lX.%08lX",
1026                           RequestBuffer->RequestIndex,
1027                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1028                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1029
1030                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1031             }
1032
1033             RDR_ByteRangeUnlockAll( userp,
1034                                     RequestBuffer->FileId,
1035                                     pBRURequestCB,
1036                                     bWow64,
1037                                     RequestBuffer->ResultBufferLength,
1038                                     &pResultCB);
1039             break;
1040         }
1041
1042         case AFS_REQUEST_TYPE_GET_VOLUME_INFO:
1043         {
1044             if (afsd_logp->enabled) {
1045                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_GET_VOLUME_INFO Index %08lX File %08lX.%08lX.%08lX.%08lX",
1046                           RequestBuffer->RequestIndex,
1047                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1048                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1049
1050                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1051             }
1052
1053             RDR_GetVolumeInfo( userp,
1054                                RequestBuffer->FileId,
1055                                bWow64,
1056                                RequestBuffer->ResultBufferLength,
1057                                &pResultCB);
1058             break;
1059         }
1060
1061         case AFS_REQUEST_TYPE_GET_VOLUME_SIZE_INFO:
1062         {
1063             if (afsd_logp->enabled) {
1064                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_GET_VOLUME_SIZE_INFO Index %08lX File %08lX.%08lX.%08lX.%08lX",
1065                           RequestBuffer->RequestIndex,
1066                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1067                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1068
1069                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1070             }
1071
1072             RDR_GetVolumeSizeInfo( userp,
1073                                    RequestBuffer->FileId,
1074                                    bWow64,
1075                                    RequestBuffer->ResultBufferLength,
1076                                    &pResultCB);
1077             break;
1078         }
1079
1080         case AFS_REQUEST_TYPE_HOLD_FID:
1081         {
1082
1083             AFSHoldFidRequestCB *pHoldFidCB = (AFSHoldFidRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1084
1085             if (afsd_logp->enabled) {
1086                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_HOLD_FID Index %08lX",
1087                           RequestBuffer->RequestIndex);
1088
1089                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1090             }
1091
1092             RDR_HoldFid( userp,
1093                          pHoldFidCB,
1094                          bFast,
1095                          RequestBuffer->ResultBufferLength,
1096                          &pResultCB);
1097
1098             break;
1099         }
1100
1101         case AFS_REQUEST_TYPE_RELEASE_FID:
1102         {
1103
1104             AFSReleaseFidRequestCB *pReleaseFidCB = (AFSReleaseFidRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1105
1106             if (afsd_logp->enabled) {
1107                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_RELEASE_FID Index %08lX",
1108                           RequestBuffer->RequestIndex);
1109
1110                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1111             }
1112
1113             RDR_ReleaseFid( userp,
1114                             pReleaseFidCB,
1115                             bFast,
1116                             RequestBuffer->ResultBufferLength,
1117                             &pResultCB);
1118
1119             break;
1120         }
1121
1122         case AFS_REQUEST_TYPE_CLEANUP_PROCESSING:
1123         {
1124
1125             AFSFileCleanupCB *pCleanupCB = (AFSFileCleanupCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1126
1127             if (afsd_logp->enabled) {
1128                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_CLEANUP_FILE Index %08lX File %08lX.%08lX.%08lX.%08lX",
1129                           RequestBuffer->RequestIndex,
1130                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1131                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1132
1133                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1134             }
1135
1136             RDR_CleanupFileEntry( userp,
1137                                   RequestBuffer->FileId,
1138                                   RequestBuffer->Name,
1139                                   RequestBuffer->NameLength,
1140                                   pCleanupCB,
1141                                   bWow64,
1142                                   bFlushFile,
1143                                   bDeleteFile,
1144                                   bUnlockFile,
1145                                   RequestBuffer->ResultBufferLength,
1146                                   &pResultCB);
1147
1148             break;
1149         }
1150
1151         case AFS_REQUEST_TYPE_PIPE_OPEN:
1152         {
1153             AFSPipeOpenCloseRequestCB *pPipeCB = (AFSPipeOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1154
1155             if (afsd_logp->enabled) {
1156                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_OPEN Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
1157                           RequestBuffer->RequestIndex,
1158                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1159                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1160
1161                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1162             }
1163
1164             RDR_PipeOpen( userp,
1165                           RequestBuffer->FileId,
1166                           RequestBuffer->Name,
1167                           RequestBuffer->NameLength,
1168                           pPipeCB,
1169                           bWow64,
1170                           RequestBuffer->ResultBufferLength,
1171                           &pResultCB);
1172             break;
1173         }
1174
1175         case AFS_REQUEST_TYPE_PIPE_WRITE:
1176         {
1177             AFSPipeIORequestCB *pPipeCB = (AFSPipeIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1178             BYTE *pPipeData = ((BYTE *)RequestBuffer->Name + RequestBuffer->DataOffset + sizeof(AFSPipeIORequestCB));
1179
1180             if (afsd_logp->enabled) {
1181                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_WRITE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
1182                           RequestBuffer->RequestIndex,
1183                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1184                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1185
1186                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1187             }
1188
1189             RDR_PipeWrite( userp,
1190                            RequestBuffer->FileId,
1191                            pPipeCB,
1192                            pPipeData,
1193                            bWow64,
1194                            RequestBuffer->ResultBufferLength,
1195                            &pResultCB);
1196             break;
1197         }
1198
1199         case AFS_REQUEST_TYPE_PIPE_READ:
1200         {
1201             AFSPipeIORequestCB *pPipeCB = (AFSPipeIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1202
1203             if (afsd_logp->enabled) {
1204                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_READ Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
1205                           RequestBuffer->RequestIndex,
1206                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1207                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1208
1209                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1210             }
1211
1212             RDR_PipeRead( userp,
1213                           RequestBuffer->FileId,
1214                           pPipeCB,
1215                           bWow64,
1216                           RequestBuffer->ResultBufferLength,
1217                           &pResultCB);
1218             break;
1219         }
1220
1221         case AFS_REQUEST_TYPE_PIPE_CLOSE:
1222         {
1223             AFSPipeOpenCloseRequestCB *pPipeCB = (AFSPipeOpenCloseRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1224
1225             if (afsd_logp->enabled) {
1226                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_CLOSE Index %08lX Parent %08lX.%08lX.%08lX.%08lX",
1227                           RequestBuffer->RequestIndex,
1228                           RequestBuffer->FileId.Cell, RequestBuffer->FileId.Volume,
1229                           RequestBuffer->FileId.Vnode, RequestBuffer->FileId.Unique);
1230
1231                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1232             }
1233
1234             RDR_PipeClose( userp,
1235                            RequestBuffer->FileId,
1236                            pPipeCB,
1237                            bWow64,
1238                            RequestBuffer->ResultBufferLength,
1239                            &pResultCB);
1240             break;
1241         }
1242
1243
1244         case AFS_REQUEST_TYPE_PIPE_TRANSCEIVE:
1245         {
1246             AFSPipeIORequestCB *pPipeCB = (AFSPipeIORequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1247             BYTE *pPipeData = ((BYTE *)RequestBuffer->Name + RequestBuffer->DataOffset + sizeof(AFSPipeIORequestCB));
1248
1249             if (afsd_logp->enabled) {
1250                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_TRANSCEIVE Index %08lX",
1251                           RequestBuffer->RequestIndex);
1252
1253                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1254             }
1255
1256             RDR_PipeTransceive( userp,
1257                                 RequestBuffer->FileId,
1258                                 pPipeCB,
1259                                 pPipeData,
1260                                 bWow64,
1261                                 RequestBuffer->ResultBufferLength,
1262                                 &pResultCB);
1263             break;
1264         }
1265
1266         case AFS_REQUEST_TYPE_PIPE_QUERY_INFO:
1267         {
1268             AFSPipeInfoRequestCB *pPipeInfoCB = (AFSPipeInfoRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1269
1270             if (afsd_logp->enabled) {
1271                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_QUERY_INFO Index %08lX",
1272                           RequestBuffer->RequestIndex);
1273
1274                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1275             }
1276
1277             RDR_PipeQueryInfo( userp,
1278                                RequestBuffer->FileId,
1279                                pPipeInfoCB,
1280                                bWow64,
1281                                RequestBuffer->ResultBufferLength,
1282                                &pResultCB);
1283             break;
1284         }
1285
1286         case AFS_REQUEST_TYPE_PIPE_SET_INFO:
1287         {
1288             AFSPipeInfoRequestCB *pPipeInfoCB = (AFSPipeInfoRequestCB *)((char *)RequestBuffer->Name + RequestBuffer->DataOffset);
1289             BYTE *pPipeData = ((BYTE *)RequestBuffer->Name + RequestBuffer->DataOffset + sizeof(AFSPipeInfoRequestCB));
1290
1291             if (afsd_logp->enabled) {
1292                 swprintf( wchBuffer, L"ProcessRequest Processing AFS_REQUEST_TYPE_PIPE_SET_INFO Index %08lX",
1293                           RequestBuffer->RequestIndex);
1294
1295                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1296             }
1297
1298             RDR_PipeSetInfo( userp,
1299                              RequestBuffer->FileId,
1300                              pPipeInfoCB,
1301                              pPipeData,
1302                              bWow64,
1303                              RequestBuffer->ResultBufferLength,
1304                              &pResultCB);
1305
1306             break;
1307         }
1308
1309         default:
1310             bUnsupported = TRUE;
1311
1312             if (afsd_logp->enabled) {
1313                 swprintf( wchBuffer, L"ProcessRequest Received unknown request type %08lX Index %08lX",
1314                           RequestBuffer->RequestType,
1315                           RequestBuffer->RequestIndex);
1316
1317                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1318             }
1319
1320             break;
1321     }
1322
1323     if( BooleanFlagOn( RequestBuffer->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS))
1324     {
1325         if (pResultCB == NULL) {
1326             // We failed probably due to a memory allocation error
1327             // unless the unsupported flag was set.
1328             pResultCB = &stResultCB;
1329             memset(&stResultCB, 0, sizeof(stResultCB));
1330             if ( bUnsupported )
1331                 pResultCB->ResultStatus = STATUS_NOT_IMPLEMENTED;
1332             else
1333                 pResultCB->ResultStatus = STATUS_NO_MEMORY;
1334         }
1335
1336         //
1337         // This is how the filter associates the response information passed in the IOCtl below to the
1338         // original call. This request index is setup by the filter and should not be modified, otherwise the
1339         // filter will not be able to locate the request in its internal queue and the blocking thread will
1340         // not be awakened
1341         //
1342
1343         pResultCB->RequestIndex = RequestBuffer->RequestIndex;
1344
1345         if (afsd_logp->enabled) {
1346             swprintf( wchBuffer,
1347                       L"ProcessRequest Responding to Index %08lX Length %08lX",
1348                       pResultCB->RequestIndex,
1349                       pResultCB->ResultBufferLength);
1350
1351             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1352         }
1353
1354         //
1355         // Now post the result back to the driver.
1356         //
1357
1358         if( !RDR_DeviceIoControl( glDevHandle,
1359                                   IOCTL_AFS_PROCESS_IRP_RESULT,
1360                                   (void *)pResultCB,
1361                                   sizeof( AFSCommResult) + pResultCB->ResultBufferLength,
1362                                   (void *)NULL,
1363                                   0,
1364                                   &bytesReturned ))
1365         {
1366             char *pBuffer = (char *)wchBuffer;
1367             gle = GetLastError();
1368             if (afsd_logp->enabled) {
1369                 swprintf( wchBuffer,
1370                           L"Failed to post IOCTL_AFS_PROCESS_IRP_RESULT gle %X", gle);
1371                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1372             }
1373
1374             if (gle != ERROR_NOT_READY) {
1375                 sprintf( pBuffer,
1376                          "Failed to post IOCTL_AFS_PROCESS_IRP_RESULT gle %X",
1377                          GetLastError());
1378                 osi_panic(pBuffer, __FILE__, __LINE__);
1379             }
1380         }
1381
1382     }
1383     else if (RequestBuffer->RequestType == AFS_REQUEST_TYPE_REQUEST_FILE_EXTENTS) {
1384
1385         if (SetFileExtentsResultCB) {
1386
1387             if (1 || afsd_logp->enabled) {
1388                 if (SetFileExtentsResultCB->ResultStatus != 0)
1389                     swprintf( wchBuffer,
1390                           L"ProcessRequest Responding Asynchronously with FAILURE to REQUEST_FILE_EXTENTS Index %08lX Count %08lX Status %08lX",
1391                           RequestBuffer->RequestIndex, SetFileExtentsResultCB->ExtentCount, SetFileExtentsResultCB->ResultStatus);
1392                 else
1393                     swprintf( wchBuffer,
1394                           L"ProcessRequest Responding Asynchronously with SUCCESS to REQUEST_FILE_EXTENTS Index %08lX Count %08lX",
1395                           RequestBuffer->RequestIndex, SetFileExtentsResultCB->ExtentCount);
1396
1397                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1398             }
1399
1400             if( (SetFileExtentsResultCB->ExtentCount != 0 ||
1401                  SetFileExtentsResultCB->ResultStatus != 0) &&
1402                 !RDR_DeviceIoControl( glDevHandle,
1403                                        IOCTL_AFS_SET_FILE_EXTENTS,
1404                                       (void *)SetFileExtentsResultCB,
1405                                       dwResultBufferLength,
1406                                       (void *)NULL,
1407                                       0,
1408                                       &bytesReturned ))
1409             {
1410                 gle = GetLastError();
1411                 if (afsd_logp->enabled) {
1412                     swprintf( wchBuffer,
1413                               L"Failed to post IOCTL_AFS_SET_FILE_EXTENTS gle %X",
1414                               gle);
1415                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1416                 }
1417
1418                 // The file system returns an error when it can't find the FID
1419                 // This is a bug in the file system but we should try to avoid
1420                 // the crash and clean up our own memory space.
1421                 //
1422                 // Since we couldn't deliver the extents to the file system
1423                 // we should release them.
1424                 if ( SetFileExtentsResultCB->ExtentCount != 0)
1425                 {
1426                     RDR_ReleaseFailedSetFileExtents( userp,
1427                                                  SetFileExtentsResultCB,
1428                                                  dwResultBufferLength);
1429                 }
1430
1431                 if (gle != ERROR_GEN_FAILURE &&
1432                     gle != ERROR_NOT_READY) {
1433                     sprintf( pBuffer,
1434                              "Failed to post IOCTL_AFS_SET_FILE_EXTENTS gle %X",
1435                              gle);
1436                     osi_panic(pBuffer, __FILE__, __LINE__);
1437                 }
1438             }
1439
1440             free(SetFileExtentsResultCB);
1441
1442       } else {
1443           /* Must be out of memory */
1444           if (afsd_logp->enabled) {
1445               swprintf( wchBuffer,
1446                         L"ProcessRequest Responding Asynchronously STATUS_NO_MEMORY to REQUEST_FILE_EXTENTS Index %08lX",
1447                         RequestBuffer->RequestIndex);
1448
1449               osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1450           }
1451
1452           RDR_SetFileStatus2( &RequestBuffer->FileId, &RequestBuffer->AuthGroup, STATUS_NO_MEMORY);
1453        }
1454     }
1455     else if (RequestBuffer->RequestType == AFS_REQUEST_TYPE_BYTE_RANGE_LOCK) {
1456
1457         if (afsd_logp->enabled) {
1458             swprintf( wchBuffer,
1459                       L"ProcessRequest Responding Asynchronously to REQUEST_TYPE_BYTE_RANGELOCK Index %08lX",
1460                       RequestBuffer->RequestIndex);
1461
1462             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1463         }
1464
1465
1466         if (SetByteRangeLockResultCB) {
1467
1468             if( !RDR_DeviceIoControl( glDevHandle,
1469                                   IOCTL_AFS_SET_BYTE_RANGE_LOCKS,
1470                                   (void *)SetByteRangeLockResultCB,
1471                                   dwResultBufferLength,
1472                                   (void *)NULL,
1473                                   0,
1474                                   &bytesReturned ))
1475             {
1476                 gle = GetLastError();
1477
1478                 if (afsd_logp->enabled) {
1479                     swprintf( wchBuffer,
1480                               L"Failed to post IOCTL_AFS_SET_BYTE_RANGE_LOCKS gle 0x%x", gle);
1481                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1482                 }
1483
1484
1485                 if (gle != ERROR_NOT_READY) {
1486                     // TODO - instead of a panic we should release the locks
1487                     sprintf( pBuffer,
1488                              "Failed to post IOCTL_AFS_SET_BYTE_RANGE_LOCKS gle %X", gle);
1489                     osi_panic(pBuffer, __FILE__, __LINE__);
1490                 }
1491             }
1492
1493             free(SetByteRangeLockResultCB);
1494         } else {
1495             /* Must be out of memory */
1496             AFSSetByteRangeLockResultCB SetByteRangeLockResultCB;
1497
1498             dwResultBufferLength = sizeof(AFSSetByteRangeLockResultCB);
1499             memset( &SetByteRangeLockResultCB, '\0', dwResultBufferLength );
1500             SetByteRangeLockResultCB.FileId = RequestBuffer->FileId;
1501             SetByteRangeLockResultCB.Result[0].Status = STATUS_NO_MEMORY;
1502
1503             if( !RDR_DeviceIoControl( glDevHandle,
1504                                       IOCTL_AFS_SET_BYTE_RANGE_LOCKS,
1505                                       (void *)&SetByteRangeLockResultCB,
1506                                       dwResultBufferLength,
1507                                       (void *)NULL,
1508                                       0,
1509                                       &bytesReturned ))
1510             {
1511                 gle = GetLastError();
1512
1513                 if (afsd_logp->enabled) {
1514                     swprintf( wchBuffer,
1515                               L"Failed to post IOCTL_AFS_SET_BYTE_RANGE_LOCKS gle 0x%x", gle);
1516                     osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1517                 }
1518
1519                 /* We were out of memory - nothing to do */
1520             }
1521         }
1522     }
1523     else {
1524
1525         if (afsd_logp->enabled) {
1526             swprintf( wchBuffer,
1527                       L"ProcessRequest Not responding to async Index %08lX",
1528                       RequestBuffer->RequestIndex);
1529
1530             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1531         }
1532     }
1533
1534     if (bRetry)
1535         goto retry;
1536
1537     if (userp)
1538         RDR_ReleaseUser(userp);
1539
1540
1541     if( pResultCB && pResultCB != &stResultCB)
1542     {
1543
1544         free( pResultCB);
1545     }
1546     return;
1547 }
1548
1549
1550 extern "C" DWORD
1551 RDR_SetFileExtents( AFSSetFileExtentsCB *pSetFileExtentsResultCB,
1552                     DWORD dwResultBufferLength)
1553 {
1554     WCHAR wchBuffer[1024];
1555     DWORD bytesReturned;
1556     DWORD gle;
1557
1558     if (1 || afsd_logp->enabled) {
1559         if (pSetFileExtentsResultCB->ResultStatus != 0)
1560             swprintf( wchBuffer,
1561                L"RDR_SetFileExtents IOCTL_AFS_SET_FILE_EXTENTS FAILURE Count %08lX Status %08lX",
1562                pSetFileExtentsResultCB->ExtentCount, pSetFileExtentsResultCB->ResultStatus);
1563         else
1564             swprintf( wchBuffer,
1565                L"RDR_SetFileExtents IOCTL_AFS_SET_FILE_EXTENTS SUCCESS Count %08lX",
1566                pSetFileExtentsResultCB->ExtentCount);
1567
1568         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1569     }
1570
1571     if( !RDR_DeviceIoControl( glDevHandle,
1572                               IOCTL_AFS_SET_FILE_EXTENTS,
1573                               (void *)pSetFileExtentsResultCB,
1574                               dwResultBufferLength,
1575                               (void *)NULL,
1576                               0,
1577                               &bytesReturned ))
1578     {
1579         gle = GetLastError();
1580         return gle;
1581     }
1582
1583     return 0;
1584 }
1585
1586
1587 extern "C" DWORD
1588 RDR_SetFileStatus( cm_fid_t *fidp,
1589                    GUID *pAuthGroup,
1590                    DWORD dwStatus)
1591 {
1592     WCHAR               wchBuffer[1024];
1593     AFSExtentFailureCB  SetFileStatusCB;
1594     DWORD               bytesReturned;
1595     DWORD               gle;
1596
1597     RDR_fid2FID(fidp, &SetFileStatusCB.FileId);
1598     memcpy(&SetFileStatusCB.AuthGroup, pAuthGroup, sizeof(GUID));
1599     SetFileStatusCB.FailureStatus = dwStatus;
1600
1601     if (afsd_logp->enabled) {
1602         swprintf( wchBuffer, L"RDR_SetFileStatus IOCTL_AFS_EXTENT_FAILURE_CB Fid %08lX.%08lX.%08lX.%08lX Status 0x%lX",
1603                   SetFileStatusCB.FileId.Cell, SetFileStatusCB.FileId.Volume,
1604                   SetFileStatusCB.FileId.Vnode, SetFileStatusCB.FileId.Unique,
1605                   dwStatus);
1606
1607         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1608     }
1609
1610     if( !RDR_DeviceIoControl( glDevHandle,
1611                               IOCTL_AFS_SET_FILE_EXTENT_FAILURE,
1612                               (void *)&SetFileStatusCB,
1613                               sizeof(AFSExtentFailureCB),
1614                               (void *)NULL,
1615                               0,
1616                               &bytesReturned ))
1617     {
1618         gle = GetLastError();
1619         return gle;
1620     }
1621
1622     return 0;
1623 }
1624
1625 static DWORD
1626 RDR_SetFileStatus2( AFSFileID *pFileId,
1627                    GUID *pAuthGroup,
1628                    DWORD dwStatus)
1629 {
1630     WCHAR               wchBuffer[1024];
1631     AFSExtentFailureCB  SetFileStatusCB;
1632     DWORD               bytesReturned;
1633     DWORD               gle;
1634
1635     memcpy(&SetFileStatusCB.FileId, pFileId, sizeof(AFSFileID));
1636     memcpy(&SetFileStatusCB.AuthGroup, pAuthGroup, sizeof(GUID));
1637     SetFileStatusCB.FailureStatus = dwStatus;
1638
1639     if (afsd_logp->enabled) {
1640         swprintf( wchBuffer, L"RDR_SetFileStatus2 IOCTL_AFS_EXTENT_FAILURE_CB Fid %08lX.%08lX.%08lX.%08lX Status 0x%lX",
1641                   SetFileStatusCB.FileId.Cell, SetFileStatusCB.FileId.Volume,
1642                   SetFileStatusCB.FileId.Vnode, SetFileStatusCB.FileId.Unique,
1643                   dwStatus);
1644
1645         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1646     }
1647
1648     if( !RDR_DeviceIoControl( glDevHandle,
1649                               IOCTL_AFS_SET_FILE_EXTENT_FAILURE,
1650                               (void *)&SetFileStatusCB,
1651                               sizeof(AFSExtentFailureCB),
1652                               (void *)NULL,
1653                               0,
1654                               &bytesReturned ))
1655     {
1656         gle = GetLastError();
1657         return gle;
1658     }
1659
1660     return 0;
1661 }
1662
1663 extern "C" DWORD
1664 RDR_RequestExtentRelease(cm_fid_t *fidp, LARGE_INTEGER numOfHeldExtents, DWORD numOfExtents, AFSFileExtentCB *extentList)
1665 {
1666
1667     HANDLE hDevHandle = NULL;
1668     DWORD bytesReturned;
1669     AFSReleaseFileExtentsCB *requestBuffer = NULL;
1670     AFSReleaseFileExtentsResultCB *responseBuffer = NULL;
1671     DWORD requestBufferLen, responseBufferLen;
1672     bool bError = false;
1673     DWORD rc = 0;
1674     WCHAR wchBuffer[256];
1675     DWORD gle;
1676
1677     if (ExitPending) {
1678         if (afsd_logp->enabled) {
1679             swprintf( wchBuffer,
1680                       L"IOCTL_AFS_RELEASE_FILE_EXTENTS request ignored due to shutdown pending");
1681
1682             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1683         }
1684
1685         OutputDebugString(L"RDR_RequestExtentRequest ignored - shutdown pending\n");
1686         return CM_ERROR_WOULDBLOCK;
1687     }
1688
1689     if (afsd_logp->enabled) {
1690         swprintf( wchBuffer,
1691                   L"IOCTL_AFS_RELEASE_FILE_EXTENTS request - number %08lX",
1692                   numOfExtents);
1693
1694         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1695     }
1696
1697     //
1698     // We use the global handle to the control device instance
1699     //
1700
1701     hDevHandle = glDevHandle;
1702
1703     //
1704     // Allocate a request buffer.
1705     //
1706
1707     requestBufferLen = sizeof( AFSReleaseFileExtentsCB) + sizeof(AFSFileExtentCB) * numOfExtents;
1708     requestBuffer = (AFSReleaseFileExtentsCB *)malloc( requestBufferLen);
1709     responseBufferLen = (sizeof( AFSReleaseFileExtentsResultCB) + sizeof( AFSReleaseFileExtentsResultFileCB)) * numOfExtents;
1710     responseBuffer = (AFSReleaseFileExtentsResultCB *)malloc( responseBufferLen);
1711
1712
1713     if( requestBuffer && responseBuffer)
1714     {
1715
1716         memset( requestBuffer, '\0', sizeof( AFSReleaseFileExtentsCB));
1717         memset( responseBuffer, '\0', responseBufferLen);
1718
1719         // If there is a FID provided, use it
1720         if (fidp && extentList)
1721         {
1722             RDR_fid2FID( fidp, &requestBuffer->FileId);
1723
1724             memcpy(&requestBuffer->FileExtents, extentList, numOfExtents * sizeof(AFSFileExtentCB));
1725
1726             requestBuffer->Flags = 0;
1727         } else {
1728
1729             requestBuffer->Flags = AFS_RELEASE_EXTENTS_FLAGS_RELEASE_ALL;
1730         }
1731
1732         // Set the number of extents to be freed
1733         // Leave the rest of the structure as zeros to indicate free anything
1734         requestBuffer->ExtentCount = numOfExtents;
1735
1736         requestBuffer->HeldExtentCount = numOfHeldExtents;
1737
1738         if( !RDR_DeviceIoControl( hDevHandle,
1739                                   IOCTL_AFS_RELEASE_FILE_EXTENTS,
1740                                   (void *)requestBuffer,
1741                                   requestBufferLen,
1742                                   (void *)responseBuffer,
1743                                   responseBufferLen,
1744                                   &bytesReturned ))
1745         {
1746             //
1747             // Error condition back from driver
1748             //
1749             if (afsd_logp->enabled) {
1750                 gle = GetLastError();
1751                 swprintf( wchBuffer,
1752                           L"Failed to post IOCTL_AFS_RELEASE_FILE_EXTENTS - gle 0x%x", gle);
1753                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1754             }
1755             rc = -1;
1756             goto cleanup;
1757         }
1758
1759         //
1760         // Go process the request
1761         //
1762
1763         if (afsd_logp->enabled) {
1764             swprintf( wchBuffer,
1765                       L"IOCTL_AFS_RELEASE_FILE_EXTENTS returns - serial number %08lX flags %lX FileCount %lX",
1766                       responseBuffer->SerialNumber, responseBuffer->Flags, responseBuffer->FileCount);
1767             osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1768         }
1769
1770         rc = RDR_ProcessReleaseFileExtentsResult( responseBuffer, bytesReturned);
1771     } else {
1772
1773         rc = ENOMEM;
1774     }
1775
1776   cleanup:
1777     if (requestBuffer)
1778         free( requestBuffer);
1779     if (responseBuffer)
1780         free( responseBuffer);
1781
1782     return rc;
1783 }
1784
1785
1786 extern "C" DWORD
1787 RDR_NetworkStatus(BOOLEAN status)
1788 {
1789
1790     HANDLE hDevHandle = NULL;
1791     DWORD bytesReturned;
1792     AFSNetworkStatusCB *requestBuffer = NULL;
1793     DWORD rc = 0;
1794     WCHAR wchBuffer[256];
1795     DWORD gle;
1796
1797     if (afsd_logp->enabled) {
1798         swprintf( wchBuffer,
1799                   L"IOCTL_AFS_NETWORK_STATUS request - status %d",
1800                   status);
1801
1802         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1803     }
1804
1805     //
1806     // We use the global handle to the control device instance
1807     //
1808
1809     hDevHandle = glDevHandle;
1810
1811     //
1812     // Allocate a request buffer.
1813     //
1814
1815     requestBuffer = (AFSNetworkStatusCB *)malloc( sizeof( AFSNetworkStatusCB));
1816
1817
1818     if( requestBuffer)
1819     {
1820
1821         memset( requestBuffer, '\0', sizeof( AFSNetworkStatusCB));
1822
1823         // Set the number of extents to be freed
1824         // Leave the rest of the structure as zeros to indicate free anything
1825         requestBuffer->Online = status;
1826
1827         if( !RDR_DeviceIoControl( hDevHandle,
1828                                   IOCTL_AFS_NETWORK_STATUS,
1829                                   (void *)requestBuffer,
1830                                   sizeof( AFSNetworkStatusCB),
1831                                   NULL,
1832                                   0,
1833                                   &bytesReturned ))
1834         {
1835             //
1836             // Error condition back from driver
1837             //
1838             if (afsd_logp->enabled) {
1839                 gle = GetLastError();
1840                 swprintf( wchBuffer,
1841                           L"Failed to post IOCTL_AFS_NETWORK_STATUS gle 0x%x",
1842                           gle);
1843                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1844             }
1845
1846             rc = -1;
1847             goto cleanup;
1848         }
1849     } else
1850         rc = ENOMEM;
1851
1852   cleanup:
1853     if (requestBuffer)
1854         free( requestBuffer);
1855
1856     return rc;
1857 }
1858
1859
1860
1861 extern "C" DWORD
1862 RDR_VolumeStatus(ULONG cellID, ULONG volID, BOOLEAN online)
1863 {
1864
1865     HANDLE hDevHandle = NULL;
1866     DWORD bytesReturned;
1867     AFSVolumeStatusCB *requestBuffer = NULL;
1868     DWORD rc = 0;
1869     WCHAR wchBuffer[256];
1870     DWORD gle;
1871
1872     if (afsd_logp->enabled) {
1873         swprintf( wchBuffer,
1874                   L"IOCTL_AFS_VOLUME_STATUS request - cell 0x%x vol 0x%x online %d",
1875                   cellID, volID, online);
1876
1877         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1878     }
1879
1880     //
1881     // We use the global handle to the control device instance
1882     //
1883
1884     hDevHandle = glDevHandle;
1885
1886     //
1887     // Allocate a request buffer.
1888     //
1889
1890     requestBuffer = (AFSVolumeStatusCB *)malloc( sizeof( AFSVolumeStatusCB));
1891
1892
1893     if( requestBuffer)
1894     {
1895
1896         memset( requestBuffer, '\0', sizeof( AFSVolumeStatusCB));
1897
1898         requestBuffer->FileID.Cell = cellID;
1899         requestBuffer->FileID.Volume = volID;
1900         requestBuffer->Online = online;
1901
1902         if( !RDR_DeviceIoControl( hDevHandle,
1903                                   IOCTL_AFS_VOLUME_STATUS,
1904                                   (void *)requestBuffer,
1905                                   sizeof( AFSVolumeStatusCB),
1906                                   NULL,
1907                                   0,
1908                                   &bytesReturned ))
1909         {
1910             //
1911             // Error condition back from driver
1912             //
1913
1914             if (afsd_logp->enabled) {
1915                 gle = GetLastError();
1916                 swprintf( wchBuffer,
1917                           L"Failed to post IOCTL_AFS_VOLUME_STATUS gle 0x%x", gle);
1918                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1919             }
1920
1921             rc = -1;
1922             goto cleanup;
1923         }
1924     } else
1925         rc = ENOMEM;
1926
1927   cleanup:
1928     if (requestBuffer)
1929         free( requestBuffer);
1930
1931     return rc;
1932 }
1933
1934 extern "C" DWORD
1935 RDR_NetworkAddrChange(void)
1936 {
1937     return 0;
1938 }
1939
1940
1941 extern "C" DWORD
1942 RDR_InvalidateVolume(ULONG cellID, ULONG volID, ULONG reason)
1943 {
1944
1945     HANDLE hDevHandle = NULL;
1946     DWORD bytesReturned;
1947     AFSInvalidateCacheCB *requestBuffer = NULL;
1948     DWORD rc = 0;
1949     WCHAR wchBuffer[256];
1950     DWORD gle;
1951
1952     if (afsd_logp->enabled) {
1953         swprintf( wchBuffer,
1954                   L"IOCTL_AFS_INVALIDATE_CACHE (vol) request - cell 0x%x vol 0x%x reason %d",
1955                   cellID, volID, reason);
1956
1957         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
1958     }
1959
1960     //
1961     // We use the global handle to the control device instance
1962     //
1963
1964     hDevHandle = glDevHandle;
1965
1966     //
1967     // Allocate a request buffer.
1968     //
1969
1970     requestBuffer = (AFSInvalidateCacheCB *)malloc( sizeof( AFSInvalidateCacheCB));
1971
1972
1973     if( requestBuffer)
1974     {
1975
1976         memset( requestBuffer, '\0', sizeof( AFSInvalidateCacheCB));
1977
1978         requestBuffer->FileID.Cell = cellID;
1979         requestBuffer->FileID.Volume = volID;
1980         requestBuffer->WholeVolume = TRUE;
1981         requestBuffer->Reason = reason;
1982
1983         if( !RDR_DeviceIoControl( hDevHandle,
1984                                   IOCTL_AFS_INVALIDATE_CACHE,
1985                                   (void *)requestBuffer,
1986                                   sizeof( AFSInvalidateCacheCB),
1987                                   NULL,
1988                                   0,
1989                                   &bytesReturned ))
1990         {
1991             //
1992             // Error condition back from driver
1993             //
1994
1995             if (afsd_logp->enabled) {
1996                 gle = GetLastError();
1997                 swprintf( wchBuffer,
1998                           L"Failed to post IOCTL_AFS_INVALIDATE_VOLUME gle 0x%x", gle);
1999                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
2000             }
2001
2002             rc = -1;
2003             goto cleanup;
2004         }
2005     } else
2006         rc = ENOMEM;
2007
2008   cleanup:
2009     if (requestBuffer)
2010         free( requestBuffer);
2011
2012     return rc;
2013 }
2014
2015
2016 extern "C" DWORD
2017 RDR_InvalidateObject(ULONG cellID, ULONG volID, ULONG vnode, ULONG uniq, ULONG hash, ULONG fileType, ULONG reason)
2018 {
2019
2020     HANDLE hDevHandle = NULL;
2021     DWORD bytesReturned;
2022     AFSInvalidateCacheCB *requestBuffer = NULL;
2023     DWORD rc = 0;
2024     WCHAR wchBuffer[256];
2025     DWORD gle;
2026
2027     if (afsd_logp->enabled) {
2028         swprintf( wchBuffer,
2029                   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",
2030                   cellID, volID, vnode, uniq, hash, fileType, reason);
2031
2032         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
2033     }
2034
2035     //
2036     // We use the global handle to the control device instance
2037     //
2038
2039     hDevHandle = glDevHandle;
2040
2041     //
2042     // Allocate a request buffer.
2043     //
2044
2045     requestBuffer = (AFSInvalidateCacheCB *)malloc( sizeof( AFSInvalidateCacheCB));
2046
2047
2048     if( requestBuffer)
2049     {
2050
2051         memset( requestBuffer, '\0', sizeof( AFSInvalidateCacheCB));
2052
2053         requestBuffer->FileID.Cell = cellID;
2054         requestBuffer->FileID.Volume = volID;
2055         requestBuffer->FileID.Vnode = vnode;
2056         requestBuffer->FileID.Unique = uniq;
2057         requestBuffer->FileID.Hash = hash;
2058         requestBuffer->FileType = fileType;
2059         requestBuffer->WholeVolume = FALSE;
2060         requestBuffer->Reason = reason;
2061
2062         if( !RDR_DeviceIoControl( hDevHandle,
2063                                   IOCTL_AFS_INVALIDATE_CACHE,
2064                                   (void *)requestBuffer,
2065                                   sizeof( AFSInvalidateCacheCB),
2066                                   NULL,
2067                                   0,
2068                                   &bytesReturned ))
2069         {
2070             //
2071             // Error condition back from driver
2072             //
2073             if (afsd_logp->enabled) {
2074                 gle = GetLastError();
2075                 swprintf( wchBuffer,
2076                           L"Failed to post IOCTL_AFS_INVALIDATE_CACHE gle 0x%x", gle);
2077                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
2078             }
2079
2080             rc = -1;
2081             goto cleanup;
2082         }
2083     } else
2084         rc = ENOMEM;
2085
2086   cleanup:
2087     if (requestBuffer)
2088         free( requestBuffer);
2089
2090     return rc;
2091 }
2092
2093
2094
2095 extern "C" DWORD
2096 RDR_SysName(ULONG Architecture, ULONG Count, WCHAR **NameList)
2097 {
2098
2099     HANDLE hDevHandle = NULL;
2100     DWORD bytesReturned;
2101     AFSSysNameNotificationCB *requestBuffer = NULL;
2102     DWORD rc = 0;
2103     WCHAR wchBuffer[256];
2104     DWORD Length;
2105     DWORD gle;
2106
2107     if (afsd_logp->enabled) {
2108         swprintf( wchBuffer,
2109                   L"IOCTL_AFS_SYSNAME_NOTIFICATION request - Arch %d Count %d",
2110                   Architecture, Count);
2111
2112         osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
2113     }
2114
2115     if (Count <= 0 || NameList == NULL)
2116         return -1;
2117
2118     //
2119     // We use the global handle to the control device instance
2120     //
2121
2122     hDevHandle = glDevHandle;
2123
2124     //
2125     // Allocate a request buffer.
2126     //
2127
2128     Length = sizeof (AFSSysNameNotificationCB) + (Count - 1) * sizeof (AFSSysName);
2129     requestBuffer = (AFSSysNameNotificationCB *)malloc( Length );
2130
2131
2132     if( requestBuffer)
2133     {
2134         unsigned int i;
2135
2136         memset( requestBuffer, '\0', Length);
2137
2138         requestBuffer->Architecture = Architecture;
2139         requestBuffer->NumberOfNames = Count;
2140         for ( i=0 ; i<Count; i++) {
2141             size_t len = wcslen(NameList[i]);
2142             requestBuffer->SysNames[i].Length = (ULONG) (len * sizeof(WCHAR));
2143             StringCchCopyNW(requestBuffer->SysNames[i].String, AFS_MAX_SYSNAME_LENGTH,
2144                             NameList[i], len);
2145         }
2146
2147         if( !RDR_DeviceIoControl( hDevHandle,
2148                                   IOCTL_AFS_SYSNAME_NOTIFICATION,
2149                                   (void *)requestBuffer,
2150                                   Length,
2151                                   NULL,
2152                                   0,
2153                                   &bytesReturned ))
2154         {
2155             //
2156             // Error condition back from driver
2157             //
2158             if (afsd_logp->enabled) {
2159                 gle = GetLastError();
2160                 swprintf( wchBuffer,
2161                           L"Failed to post IOCTL_AFS_SYSNAME_NOTIFICATION gle 0x%x", gle);
2162                 osi_Log1(afsd_logp, "%S", osi_LogSaveStringW(afsd_logp, wchBuffer));
2163             }
2164
2165             rc = -1;
2166             goto cleanup;
2167         }
2168     } else
2169         rc = ENOMEM;
2170
2171   cleanup:
2172     if (requestBuffer)
2173         free( requestBuffer);
2174
2175     return rc;
2176 }
2177
2178 extern "C" VOID
2179 RDR_Suspend( VOID)
2180 {
2181     ResetEvent( RDR_SuspendEvent);
2182 }
2183
2184 extern "C" VOID
2185 RDR_Resume( VOID)
2186 {
2187     SetEvent( RDR_SuspendEvent);
2188 }