Windows: Wait for memory allocation if necessary
[openafs.git] / src / WINNT / afsrdr / kernel / fs / AFSProcessSupport.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3  * Copyright (c) 2009, 2010, 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
8  * are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * - Redistributions in binary form must reproduce the above copyright
13  *   notice,
14  *   this list of conditions and the following disclaimer in the
15  *   documentation
16  *   and/or other materials provided with the distribution.
17  * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18  *   nor the names of their contributors may be used to endorse or promote
19  *   products derived from this software without specific prior written
20  *   permission from Kernel Drivers, LLC and Your File System, Inc.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 //
36 // File: AFSProcessSupport.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 void
42 AFSProcessNotify( IN HANDLE  ParentId,
43                   IN HANDLE  ProcessId,
44                   IN BOOLEAN  Create)
45 {
46
47     NTSTATUS ntStatus = STATUS_SUCCESS;
48     AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL;
49     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
50     AFSProcessAuthGroupCB *pProcessAuthGroup = NULL, *pLastAuthGroup = NULL;
51     AFSThreadCB *pThreadCB = NULL, *pNextThreadCB = NULL;
52
53     __Enter
54     {
55
56         //
57         // If this is a create notification then update our tree, otherwise remove the
58         // entry
59         //
60
61         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
62                       AFS_TRACE_LEVEL_VERBOSE,
63                       "AFSProcessNotify Acquiring Control ProcessTree.TreeLock lock %08lX EXCL %08lX\n",
64                       pDeviceExt->Specific.Control.ProcessTree.TreeLock,
65                       PsGetCurrentThread());
66
67         AFSAcquireExcl( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
68                         TRUE);
69
70         if( Create)
71         {
72
73             AFSDbgLogMsg( AFS_SUBSYSTEM_PROCESS_PROCESSING,
74                           AFS_TRACE_LEVEL_VERBOSE,
75                           "AFSProcessNotify CREATE Parent %08lX Process %08lX %08lX\n",
76                           ParentId,
77                           ProcessId,
78                           PsGetCurrentThread());
79
80             pProcessCB = AFSInitializeProcessCB( (ULONGLONG)ParentId,
81                                                  (ULONGLONG)ProcessId);
82
83             if( pProcessCB != NULL)
84             {
85                 pProcessCB->CreatingThread = (ULONGLONG)PsGetCurrentThreadId();
86             }
87
88             try_return( ntStatus);
89         }
90
91         //
92         // It's a remove so pull the entry
93         //
94
95         AFSDbgLogMsg( AFS_SUBSYSTEM_PROCESS_PROCESSING,
96                       AFS_TRACE_LEVEL_VERBOSE,
97                       "AFSProcessNotify DESTROY Process %08lX %08lX\n",
98                       ProcessId,
99                       PsGetCurrentThread());
100
101         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
102                                        (ULONGLONG)ProcessId,
103                                        (AFSBTreeEntry **)&pProcessCB);
104
105         if( NT_SUCCESS( ntStatus) &&
106             pProcessCB != NULL)
107         {
108
109             AFSRemoveHashEntry( &pDeviceExt->Specific.Control.ProcessTree.TreeHead,
110                                 (AFSBTreeEntry *)pProcessCB);
111
112             pProcessAuthGroup = pProcessCB->AuthGroupList;
113
114             while( pProcessAuthGroup != NULL)
115             {
116
117                 pLastAuthGroup = pProcessAuthGroup->Next;
118
119                 ExFreePool( pProcessAuthGroup);
120
121                 pProcessAuthGroup = pLastAuthGroup;
122             }
123
124             pThreadCB = pProcessCB->ThreadList;
125
126             while( pThreadCB != NULL)
127             {
128
129                 pNextThreadCB = pThreadCB->Next;
130
131                 ExFreePool( pThreadCB);
132
133                 pThreadCB = pNextThreadCB;
134             }
135
136             ExDeleteResourceLite( &pProcessCB->Lock);
137
138             ExFreePool( pProcessCB);
139         }
140         else
141         {
142             AFSDbgLogMsg( AFS_SUBSYSTEM_PROCESS_PROCESSING,
143                           AFS_TRACE_LEVEL_WARNING,
144                           "AFSProcessNotify Process %08lX not found in ProcessTree Status %08lX %08lX\n",
145                           ProcessId,
146                           ntStatus,
147                           PsGetCurrentThread());
148         }
149
150 try_exit:
151
152         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
153
154     }
155
156     return;
157 }
158
159 //
160 // AFSValidateProcessEntry verifies the consistency of the current process
161 // entry which includes assigning an authentication group ACE if one is not
162 // present.  A reference to the active authentication group GUID is returned.
163 //
164
165 GUID *
166 AFSValidateProcessEntry( void)
167 {
168
169     GUID *pAuthGroup = NULL;
170     NTSTATUS ntStatus = STATUS_SUCCESS;
171     AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL;
172     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
173     ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId();
174     UNICODE_STRING uniSIDString;
175     ULONG ulSIDHash = 0;
176     AFSSIDEntryCB *pSIDEntryCB = NULL;
177     ULONG ulSessionId = 0;
178     ULONGLONG ullTableHash = 0;
179     AFSThreadCB *pParentThreadCB = NULL;
180     UNICODE_STRING uniGUID;
181     BOOLEAN bImpersonation = FALSE;
182
183     __Enter
184     {
185
186         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
187                       AFS_TRACE_LEVEL_VERBOSE,
188                       "AFSValidateProcessEntry Acquiring Control ProcessTree.TreeLock lock %08lX SHARED %08lX\n",
189                       pDeviceExt->Specific.Control.ProcessTree.TreeLock,
190                       PsGetCurrentThread());
191
192         uniSIDString.Length = 0;
193         uniSIDString.MaximumLength = 0;
194         uniSIDString.Buffer = NULL;
195
196         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
197                           TRUE);
198
199         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
200                       AFS_TRACE_LEVEL_VERBOSE,
201                       "%s Entry for ProcessID %I64X\n",
202                       __FUNCTION__,
203                       ullProcessID);
204
205         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
206                                        (ULONGLONG)ullProcessID,
207                                        (AFSBTreeEntry **)&pProcessCB);
208
209         if( !NT_SUCCESS( ntStatus) ||
210             pProcessCB == NULL)
211         {
212
213             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
214                           AFS_TRACE_LEVEL_ERROR,
215                           "%s Failed to locate process entry for ProcessID %I64X\n",
216                           __FUNCTION__,
217                           ullProcessID);
218
219             ASSERT( FALSE);
220             AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
221             try_return( ntStatus = STATUS_UNSUCCESSFUL);
222         }
223
224         //
225         // Locate and lock the ParentProcessCB if we have one
226         //
227
228         if( pProcessCB->ParentProcessId != 0)
229         {
230
231             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
232                           AFS_TRACE_LEVEL_VERBOSE,
233                           "%s Locating process entry for Parent ProcessID %I64X\n",
234                           __FUNCTION__,
235                           pProcessCB->ParentProcessId);
236
237             ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
238                                            (ULONGLONG)pProcessCB->ParentProcessId,
239                                            (AFSBTreeEntry **)&pParentProcessCB);
240
241             if( NT_SUCCESS( ntStatus) &&
242                 pParentProcessCB != NULL)
243             {
244                 AFSAcquireExcl( &pParentProcessCB->Lock,
245                                 TRUE);
246
247                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
248                               AFS_TRACE_LEVEL_VERBOSE,
249                               "%s Located process entry for Parent ProcessID %I64X\n",
250                               __FUNCTION__,
251                               pProcessCB->ParentProcessId);
252             }
253         }
254         else
255         {
256
257             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
258                           AFS_TRACE_LEVEL_VERBOSE,
259                           "%s No parent ID for ProcessID %I64X\n",
260                           __FUNCTION__,
261                           ullProcessID);
262         }
263
264         AFSAcquireExcl( &pProcessCB->Lock,
265                         TRUE);
266
267         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
268
269         //
270         // Locate the SID for the caller
271         //
272
273         ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation);
274
275         if( !NT_SUCCESS( ntStatus))
276         {
277
278             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
279                           AFS_TRACE_LEVEL_ERROR,
280                           "%s Failed to locate callers SID for ProcessID %I64X\n",
281                           __FUNCTION__,
282                           ullProcessID);
283
284             try_return( ntStatus);
285         }
286
287         ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);
288
289         if( ulSessionId == (ULONG)-1)
290         {
291
292             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
293                           AFS_TRACE_LEVEL_ERROR,
294                           "%s Failed to retrieve session ID for ProcessID %I64X\n",
295                           __FUNCTION__,
296                           ullProcessID);
297
298             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
299         }
300
301         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
302                       AFS_TRACE_LEVEL_VERBOSE,
303                       "%s Retrieved callers SID %wZ for ProcessID %I64X Session %08lX\n",
304                       __FUNCTION__,
305                       &uniSIDString,
306                       ullProcessID,
307                       ulSessionId);
308
309         //
310         // If there is an Auth Group for the current process,
311         // our job is finished.
312         //
313
314         if ( bImpersonation == FALSE)
315         {
316             pAuthGroup = pProcessCB->ActiveAuthGroup;
317
318             if( pAuthGroup != NULL &&
319                 !AFSIsNoPAGAuthGroup( pAuthGroup))
320             {
321
322                 uniGUID.Buffer = NULL;
323
324                 RtlStringFromGUID( *pAuthGroup,
325                                    &uniGUID);
326
327                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
328                               AFS_TRACE_LEVEL_VERBOSE,
329                               "%s Located valid AuthGroup GUID %wZ for SID %wZ ProcessID %I64X Session %08lX\n",
330                               __FUNCTION__,
331                               &uniGUID,
332                               &uniSIDString,
333                               ullProcessID,
334                               ulSessionId);
335
336                 if( uniGUID.Buffer != NULL)
337                 {
338                     RtlFreeUnicodeString( &uniGUID);
339                 }
340
341                 try_return( ntStatus = STATUS_SUCCESS);
342             }
343
344             //
345             // The current process does not yet have an Auth Group.  Try to inherit
346             // one from the parent process thread that created this process.
347             //
348
349             if( pParentProcessCB != NULL)
350             {
351
352                 for ( pParentThreadCB = pParentProcessCB->ThreadList;
353                       pParentThreadCB != NULL;
354                       pParentThreadCB = pParentThreadCB->Next)
355                 {
356
357                     if( pParentThreadCB->ThreadId == pProcessCB->CreatingThread)
358                     {
359                         break;
360                     }
361                 }
362
363                 //
364                 // If the creating thread was found and it has a thread specific
365                 // Auth Group, use that even if it is the No PAG
366                 //
367
368                 if( pParentThreadCB != NULL &&
369                     pParentThreadCB->ActiveAuthGroup != NULL &&
370                     !AFSIsNoPAGAuthGroup( pParentThreadCB->ActiveAuthGroup))
371                 {
372                     pProcessCB->ActiveAuthGroup = pParentThreadCB->ActiveAuthGroup;
373
374                     uniGUID.Buffer = NULL;
375
376                     RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
377                                        &uniGUID);
378
379                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
380                                   AFS_TRACE_LEVEL_VERBOSE,
381                                   "%s PID %08lX Session %08lX inherited Active AuthGroup %wZ from thread %I64X\n",
382                                   __FUNCTION__,
383                                   ullProcessID,
384                                   ulSessionId,
385                                   &uniGUID,
386                                   pParentThreadCB->ThreadId);
387
388                     if( uniGUID.Buffer != NULL)
389                     {
390                         RtlFreeUnicodeString( &uniGUID);
391                     }
392                 }
393
394                 //
395                 // If the parent thread was not found or does not have an auth group
396                 //
397
398                 else if( pParentProcessCB->ActiveAuthGroup != NULL &&
399                          !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
400                 {
401                     pProcessCB->ActiveAuthGroup = pParentProcessCB->ActiveAuthGroup;
402
403                     uniGUID.Buffer = NULL;
404
405                     RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
406                                        &uniGUID);
407
408                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
409                                   AFS_TRACE_LEVEL_VERBOSE,
410                                   "%s PID %08lX Session %08lX inherited Active AuthGroup %wZ from parent PID %I64X\n",
411                                   __FUNCTION__,
412                                   ullProcessID,
413                                   ulSessionId,
414                                   &uniGUID,
415                                   pParentProcessCB->TreeEntry.HashIndex);
416
417                     if( uniGUID.Buffer != NULL)
418                     {
419                         RtlFreeUnicodeString( &uniGUID);
420                     }
421                 }
422
423                 //
424                 // If an Auth Group was inherited, set it to be the active group
425                 //
426
427                 if( pProcessCB->ActiveAuthGroup != NULL &&
428                     !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
429                 {
430                     pAuthGroup = pProcessCB->ActiveAuthGroup;
431
432                     uniGUID.Buffer = NULL;
433
434                     RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
435                                        &uniGUID);
436
437                     AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
438                                   AFS_TRACE_LEVEL_VERBOSE,
439                                   "%s Returning(1) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
440                                   __FUNCTION__,
441                                   &uniGUID,
442                                   &uniSIDString,
443                                   ullProcessID,
444                                   ulSessionId);
445
446                     if( uniGUID.Buffer != NULL)
447                     {
448                         RtlFreeUnicodeString( &uniGUID);
449                     }
450
451                     try_return( ntStatus);
452                 }
453             }
454         }
455
456         //
457         // If no Auth Group was inherited, assign one based upon the Session and SID
458         //
459
460         ntStatus = RtlHashUnicodeString( &uniSIDString,
461                                          TRUE,
462                                          HASH_STRING_ALGORITHM_DEFAULT,
463                                          &ulSIDHash);
464
465         if( !NT_SUCCESS( ntStatus))
466         {
467
468             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
469                           AFS_TRACE_LEVEL_ERROR,
470                           "%s Failed to hash SID %wZ for PID %I64X Session %08lX Status %08lX\n",
471                           __FUNCTION__,
472                           &uniSIDString,
473                           ullProcessID,
474                           ulSessionId,
475                           ntStatus);
476
477             try_return( ntStatus);
478         }
479
480         ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);
481
482         AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
483                           TRUE);
484
485         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
486                                        (ULONGLONG)ullTableHash,
487                                        (AFSBTreeEntry **)&pSIDEntryCB);
488
489         if( !NT_SUCCESS( ntStatus) ||
490             pSIDEntryCB == NULL)
491         {
492
493             AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
494
495             AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
496                             TRUE);
497
498             ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
499                                            (ULONGLONG)ullTableHash,
500                                            (AFSBTreeEntry **)&pSIDEntryCB);
501
502             if( !NT_SUCCESS( ntStatus) ||
503                 pSIDEntryCB == NULL)
504             {
505
506                 pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
507                                                                          sizeof( AFSSIDEntryCB),
508                                                                          AFS_AG_ENTRY_CB_TAG);
509
510                 if( pSIDEntryCB == NULL)
511                 {
512
513                     AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
514
515                     try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
516                 }
517
518                 RtlZeroMemory( pSIDEntryCB,
519                                sizeof( AFSSIDEntryCB));
520
521                 pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash;
522
523                 while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY);
524
525                 uniGUID.Buffer = NULL;
526
527                 RtlStringFromGUID( pSIDEntryCB->AuthGroup,
528                                    &uniGUID);
529
530                 AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
531                               AFS_TRACE_LEVEL_VERBOSE,
532                               "%s  SID %wZ PID %I64X Session %08lX generated NEW AG %wZ\n",
533                               __FUNCTION__,
534                               &uniSIDString,
535                               ullProcessID,
536                               ulSessionId,
537                               &uniGUID);
538
539                 if( uniGUID.Buffer != NULL)
540                 {
541                     RtlFreeUnicodeString( &uniGUID);
542                 }
543
544                 if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL)
545                 {
546                     pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB;
547                 }
548                 else
549                 {
550                     AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
551                                         &pSIDEntryCB->TreeEntry);
552                 }
553             }
554
555             AFSConvertToShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
556         }
557
558
559         AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
560
561         //
562         // Store the auth group into the process cb
563         //
564
565         pProcessCB->ActiveAuthGroup = &pSIDEntryCB->AuthGroup;
566
567         uniGUID.Buffer = NULL;
568
569         RtlStringFromGUID( pSIDEntryCB->AuthGroup,
570                            &uniGUID);
571
572         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
573                       AFS_TRACE_LEVEL_VERBOSE,
574                       "%s SID %wZ PID %I64X Session %08lX assigned AG %wZ\n",
575                       __FUNCTION__,
576                       &uniSIDString,
577                       ullProcessID,
578                       ulSessionId,
579                       &uniGUID);
580
581         if( uniGUID.Buffer != NULL)
582         {
583             RtlFreeUnicodeString( &uniGUID);
584         }
585
586         //
587         // Set the AFS_PROCESS_LOCAL_SYSTEM_AUTH flag if the process SID
588         // is LOCAL_SYSTEM
589         //
590
591         if( AFSIsLocalSystemSID( &uniSIDString))
592         {
593             SetFlag( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH);
594
595             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
596                           AFS_TRACE_LEVEL_VERBOSE,
597                           "%s Setting PID %I64X Session %08lX with LOCAL SYSTEM AUTHORITY\n",
598                           __FUNCTION__,
599                           ullProcessID,
600                           ulSessionId);
601         }
602
603         //
604         // Return the auth group
605         //
606
607         pAuthGroup = pProcessCB->ActiveAuthGroup;
608
609         uniGUID.Buffer = NULL;
610
611         RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
612                            &uniGUID);
613
614         AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
615                       AFS_TRACE_LEVEL_VERBOSE,
616                       "%s Returning(2) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
617                       __FUNCTION__,
618                       &uniGUID,
619                       &uniSIDString,
620                       ullProcessID,
621                       ulSessionId);
622
623         if( uniGUID.Buffer != NULL)
624         {
625             RtlFreeUnicodeString( &uniGUID);
626         }
627
628 try_exit:
629
630         if( pProcessCB != NULL)
631         {
632
633             if( bImpersonation == FALSE &&
634                 !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET) &&
635                 NT_SUCCESS( ntStatus))
636             {
637                 ntStatus = AFSProcessSetProcessDacl( pProcessCB);
638
639                 if( !NT_SUCCESS( ntStatus))
640                 {
641                     pAuthGroup = NULL;
642                 }
643                 else
644                 {
645                     SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET);
646                 }
647             }
648
649             AFSReleaseResource( &pProcessCB->Lock);
650         }
651
652         if( pParentProcessCB != NULL)
653         {
654             AFSReleaseResource( &pParentProcessCB->Lock);
655         }
656
657         if( uniSIDString.Length > 0)
658         {
659             RtlFreeUnicodeString( &uniSIDString);
660         }
661     }
662
663     return pAuthGroup;
664 }
665
666 BOOLEAN
667 AFSIs64BitProcess( IN ULONGLONG ProcessId)
668 {
669
670     NTSTATUS ntStatus = STATUS_SUCCESS;
671     BOOLEAN bIs64Bit = FALSE;
672     AFSProcessCB *pProcessCB = NULL;
673     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
674
675     __Enter
676     {
677
678         AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
679                       AFS_TRACE_LEVEL_VERBOSE,
680                       "AFSIs64BitProcess Acquiring Control ProcessTree.TreeLock lock %08lX SHARED %08lX\n",
681                       pDeviceExt->Specific.Control.ProcessTree.TreeLock,
682                       PsGetCurrentThread());
683
684         AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
685                           TRUE);
686
687         ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
688                                        (ULONGLONG)ProcessId,
689                                        (AFSBTreeEntry **)&pProcessCB);
690
691         if( pProcessCB != NULL)
692         {
693             bIs64Bit = BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
694         }
695
696         AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
697     }
698
699     return bIs64Bit;
700 }
701
702 AFSProcessCB *
703 AFSInitializeProcessCB( IN ULONGLONG ParentProcessId,
704                         IN ULONGLONG ProcessId)
705 {
706
707     AFSProcessCB *pProcessCB = NULL;
708     AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
709
710     __Enter
711     {
712
713         pProcessCB = (AFSProcessCB *)AFSExAllocatePoolWithTag( NonPagedPool,
714                                                                sizeof( AFSProcessCB),
715                                                                AFS_PROCESS_CB_TAG);
716
717         if( pProcessCB == NULL)
718         {
719             try_return( pProcessCB);
720         }
721
722         RtlZeroMemory( pProcessCB,
723                        sizeof( AFSProcessCB));
724
725         pProcessCB->TreeEntry.HashIndex = (ULONGLONG)ProcessId;
726
727         pProcessCB->ParentProcessId = (ULONGLONG)ParentProcessId;
728
729 #if defined(_WIN64)
730
731         if( !IoIs32bitProcess( NULL))
732         {
733             SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
734         }
735
736 #endif
737
738         if( pDeviceExt->Specific.Control.ProcessTree.TreeHead == NULL)
739         {
740             pDeviceExt->Specific.Control.ProcessTree.TreeHead = (AFSBTreeEntry *)pProcessCB;
741         }
742         else
743         {
744             AFSInsertHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
745                                 &pProcessCB->TreeEntry);
746         }
747
748         ExInitializeResourceLite( &pProcessCB->Lock);
749
750         pProcessCB->ActiveAuthGroup = &AFSNoPAGAuthGroup;
751
752 try_exit:
753
754         NOTHING;
755     }
756
757     return pProcessCB;
758 }
759
760 AFSThreadCB *
761 AFSInitializeThreadCB( IN AFSProcessCB *ProcessCB,
762                        IN ULONGLONG ThreadId)
763 {
764
765     AFSThreadCB *pThreadCB = NULL, *pCurrentThreadCB = NULL;
766
767     __Enter
768     {
769
770         pThreadCB = (AFSThreadCB *)AFSExAllocatePoolWithTag( NonPagedPool,
771                                                              sizeof( AFSThreadCB),
772                                                              AFS_PROCESS_CB_TAG);
773
774         if( pThreadCB == NULL)
775         {
776             try_return( pThreadCB);
777         }
778
779         RtlZeroMemory( pThreadCB,
780                        sizeof( AFSThreadCB));
781
782         pThreadCB->ThreadId = ThreadId;
783
784         if( ProcessCB->ThreadList == NULL)
785         {
786             ProcessCB->ThreadList = pThreadCB;
787         }
788         else
789         {
790
791             pCurrentThreadCB = ProcessCB->ThreadList;
792
793             while( pCurrentThreadCB != NULL)
794             {
795
796                 if( pCurrentThreadCB->Next == NULL)
797                 {
798                     pCurrentThreadCB->Next = pThreadCB;
799                     break;
800                 }
801
802                 pCurrentThreadCB = pCurrentThreadCB->Next;
803             }
804         }
805
806 try_exit:
807
808         NOTHING;
809     }
810
811     return pThreadCB;
812 }