windows-memdump-20080814
[openafs.git] / src / WINNT / afsd / smb.c
index 6005d9f..eb01076 100644 (file)
@@ -819,7 +819,11 @@ void smb_UnixTimeFromDosUTime(time_t *unixTimep, afs_uint32 dosTime)
     *unixTimep = dosTime + smb_localZero;
 }
 
+#ifdef DEBUG_SMB_REFCOUNT
+smb_vc_t *smb_FindVCDbg(unsigned short lsn, int flags, int lana, char *file, long line)
+#else
 smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana)
+#endif
 {
     smb_vc_t *vcp;
 
@@ -898,6 +902,12 @@ smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana)
             osi_Log0(smb_logp, "WARNING: numVCs wrapping around");
         }
     }
+#ifdef DEBUG_SMB_REFCOUNT
+    if (vcp) {
+        afsi_log("%s:%d smb_FindVC vcp 0x%p ref %d", file, line, vcp, vcp->refCount);
+        osi_Log4(smb_logp,"%s:%d smb_FindVC vcp 0x%p ref %d", file, line, vcp, vcp->refCount);
+    }
+#endif
     lock_ReleaseWrite(&smb_rctLock);
     lock_ReleaseWrite(&smb_globalLock);
     return vcp;
@@ -916,15 +926,25 @@ int smb_IsStarMask(clientchar_t *maskp)
     return 0;
 }
 
+#ifdef DEBUG_SMB_REFCOUNT
+void smb_ReleaseVCInternalDbg(smb_vc_t *vcp, char * file, long line)
+#define smb_ReleaseVCInternal(a) smb_ReleaseVCInternalDbg(a, file, line)
+#else
 void smb_ReleaseVCInternal(smb_vc_t *vcp)
+#endif
 {
     smb_vc_t **vcpp;
     smb_vc_t * avcp;
 
+    lock_AssertWrite(&smb_rctLock);
     vcp->refCount--;
 
     if (vcp->refCount == 0) {
         if (vcp->flags & SMB_VCFLAG_ALREADYDEAD) {
+#ifdef DEBUG_SMB_REFCOUNT
+            afsi_log("%s:%d smb_ReleaseVCInternal vcp 0x%p is dead ref %d", file, line, vcp, vcp->refCount);
+            osi_Log4(smb_logp,"%s:%d smb_ReleaseVCInternal vcp 0x%p is dead ref %d", file, line, vcp, vcp->refCount);
+#endif
             /* remove VCP from smb_deadVCsp */
             for (vcpp = &smb_deadVCsp; *vcpp; vcpp = &((*vcpp)->nextp)) {
                 if (*vcpp == vcp) {
@@ -936,45 +956,73 @@ void smb_ReleaseVCInternal(smb_vc_t *vcp)
             memset(vcp,0,sizeof(smb_vc_t));
             free(vcp);
         } else {
+#ifdef DEBUG_SMB_REFCOUNT
+            afsi_log("%s:%d smb_ReleaseVCInternal vcp 0x%p is alive ref %d", file, line, vcp, vcp->refCount);
+#endif
             for (avcp = smb_allVCsp; avcp; avcp = avcp->nextp) {
                 if (avcp == vcp)
                     break;
             }
             osi_Log3(smb_logp,"VCP not dead and %sin smb_allVCsp vcp %x ref %d",
-                      avcp?"not ":"",vcp, vcp->refCount);
-#ifdef DEBUG
-            GenerateMiniDump(NULL);
-#endif
+                      avcp?"":"not ",vcp, vcp->refCount);
+
             /* This is a wrong.  However, I suspect that there is an undercount
              * and I don't want to release 1.4.1 in a state that will allow
              * smb_vc_t objects to be deallocated while still in the
              * smb_allVCsp list.  The list is supposed to keep a reference
              * to the smb_vc_t.  Put it back.
              */
-            vcp->refCount++;
+            if (avcp) {
+                vcp->refCount++;
+#ifdef DEBUG_SMB_REFCOUNT
+                afsi_log("%s:%d smb_ReleaseVCInternal vcp 0x%p is in smb_allVCsp ref %d", file, line, vcp, vcp->refCount);
+                osi_Log4(smb_logp,"%s:%d smb_ReleaseVCInternal vcp 0x%p is in smb_allVCsp ref %d", file, line, vcp, vcp->refCount);
+#endif
+            }
         }
     } else if (vcp->flags & SMB_VCFLAG_ALREADYDEAD) {
         /* The reference count is non-zero but the VC is dead.
          * This implies that some FIDs, TIDs, etc on the VC have yet to 
-         * be cleaned up.  Add a reference that will be dropped by
+         * be cleaned up.  If we were not called by smb_CleanupDeadVC(),
+         * add a reference that will be dropped by
          * smb_CleanupDeadVC() and try to cleanup the VC again.
          * Eventually the refCount will drop to zero when all of the
          * active threads working with the VC end their task.
          */
-        vcp->refCount++;        /* put the refCount back */
-        lock_ReleaseWrite(&smb_rctLock);
-        smb_CleanupDeadVC(vcp);
-        lock_ObtainWrite(&smb_rctLock);
+        if (!(vcp->flags & SMB_VCFLAG_CLEAN_IN_PROGRESS)) {
+            vcp->refCount++;        /* put the refCount back */
+            lock_ReleaseWrite(&smb_rctLock);
+            smb_CleanupDeadVC(vcp);
+#ifdef DEBUG_SMB_REFCOUNT
+            afsi_log("%s:%d smb_ReleaseVCInternal vcp 0x%p after CleanupDeadVC ref %d", file, line, vcp, vcp->refCount);
+            osi_Log4(smb_logp,"%s:%d smb_ReleaseVCInternal vcp 0x%p after CleanupDeadVC ref %d", file, line, vcp, vcp->refCount);
+#endif
+            lock_ObtainWrite(&smb_rctLock);
+        }
+    } else {
+#ifdef DEBUG_SMB_REFCOUNT
+        afsi_log("%s:%d smb_ReleaseVCInternal vcp 0x%p ref %d", file, line, vcp, vcp->refCount);
+        osi_Log4(smb_logp,"%s:%d smb_ReleaseVCInternal vcp 0x%p ref %d", file, line, vcp, vcp->refCount);
+#endif
     }
 }
 
+#ifdef DEBUG_SMB_REFCOUNT
+void smb_ReleaseVCNoLockDbg(smb_vc_t *vcp, char * file, long line)
+#else
 void smb_ReleaseVCNoLock(smb_vc_t *vcp)
+#endif
 {
+    lock_AssertWrite(&smb_rctLock);
     osi_Log2(smb_logp,"smb_ReleaseVCNoLock vcp %x ref %d",vcp, vcp->refCount);
     smb_ReleaseVCInternal(vcp);
 }       
 
+#ifdef DEBUG_SMB_REFCOUNT
+void smb_ReleaseVCDbg(smb_vc_t *vcp, char * file, long line)
+#else
 void smb_ReleaseVC(smb_vc_t *vcp)
+#endif
 {
     lock_ObtainWrite(&smb_rctLock);
     osi_Log2(smb_logp,"smb_ReleaseVC       vcp %x ref %d",vcp, vcp->refCount);
@@ -982,17 +1030,36 @@ void smb_ReleaseVC(smb_vc_t *vcp)
     lock_ReleaseWrite(&smb_rctLock);
 }       
 
+#ifdef DEBUG_SMB_REFCOUNT
+void smb_HoldVCNoLockDbg(smb_vc_t *vcp, char * file, long line)
+#else
 void smb_HoldVCNoLock(smb_vc_t *vcp)
+#endif
 {
+    lock_AssertWrite(&smb_rctLock);
     vcp->refCount++;
+#ifdef DEBUG_SMB_REFCOUNT
+    afsi_log("%s:%d smb_HoldVCNoLock vcp 0x%p ref %d", file, line, vcp, vcp->refCount);
+    osi_Log4(smb_logp,"%s:%d smb_HoldVCNoLock vcp 0x%p ref %d", file, line, vcp, vcp->refCount);
+#else
     osi_Log2(smb_logp,"smb_HoldVCNoLock vcp %x ref %d",vcp, vcp->refCount);
+#endif
 }       
 
+#ifdef DEBUG_SMB_REFCOUNT
+void smb_HoldVCDbg(smb_vc_t *vcp, char * file, long line)
+#else
 void smb_HoldVC(smb_vc_t *vcp)
+#endif
 {
     lock_ObtainWrite(&smb_rctLock);
     vcp->refCount++;
+#ifdef DEBUG_SMB_REFCOUNT
+    afsi_log("%s:%d smb_HoldVC       vcp 0x%p ref %d", file, line, vcp, vcp->refCount);
+    osi_Log4(smb_logp,"%s:%d smb_HoldVC       vcp 0x%p ref %d", file, line, vcp, vcp->refCount);
+#else
     osi_Log2(smb_logp,"smb_HoldVC       vcp %x ref %d",vcp, vcp->refCount);
+#endif
     lock_ReleaseWrite(&smb_rctLock);
 }       
 
@@ -1084,15 +1151,14 @@ void smb_CleanupDeadVC(smb_vc_t *vcp)
     }
 
     /* The vcp is now on the deadVCsp list.  We intentionally drop the
-     * reference so that the refcount can reach 0 and we can delete it */
-    refCount = vcp->refCount;
-    smb_ReleaseVCNoLock(vcp);
-
-    /* 
+     * reference so that the refcount can reach 0 and we can delete it 
+     *
      * If the refCount == 1 going into the ReleaseVCNoLock call 
      * the object will be freed and it won't be safe to clear 
      * the flag.
      */
+    refCount = vcp->refCount;
+    smb_ReleaseVCNoLock(vcp);
     if (refCount > 1) {
         lock_ObtainMutex(&vcp->mx);
         vcp->flags &= ~SMB_VCFLAG_CLEAN_IN_PROGRESS;
@@ -1103,7 +1169,11 @@ void smb_CleanupDeadVC(smb_vc_t *vcp)
     osi_Log1(smb_logp, "Finished cleaning up dead vcp 0x%x", vcp);
 }
 
+#ifdef DEBUG_SMB_REFCOUNT
+smb_tid_t *smb_FindTIDDbg(smb_vc_t *vcp, unsigned short tid, int flags, char * file, long line)
+#else
 smb_tid_t *smb_FindTID(smb_vc_t *vcp, unsigned short tid, int flags)
+#endif
 {
     smb_tid_t *tidp;
 
@@ -1132,43 +1202,74 @@ smb_tid_t *smb_FindTID(smb_vc_t *vcp, unsigned short tid, int flags)
         lock_InitializeMutex(&tidp->mx, "tid_t mutex");
         tidp->tid = tid;
     }
+#ifdef DEBUG_SMB_REFCOUNT
+    if (tidp) {
+        afsi_log("%s:%d smb_FindTID tidp 0x%p ref %d", file, line, tidp, tidp->refCount);
+        osi_Log4(smb_logp,"%s:%d smb_FindTID tidp 0x%p ref %d", file, line, tidp, tidp->refCount);
+    }
+#endif
     lock_ReleaseWrite(&smb_rctLock);
     return tidp;
 }
 
+#ifdef DEBUG_SMB_REFCOUNT
+void smb_HoldTIDNoLockDbg(smb_tid_t *tidp, char * file, long line)
+#else
 void smb_HoldTIDNoLock(smb_tid_t *tidp)
+#endif
 {
+    lock_AssertWrite(&smb_rctLock);
     tidp->refCount++;
+#ifdef DEBUG_SMB_REFCOUNT
+    afsi_log("%s:%d smb_HoldTIDNoLock tidp 0x%p ref %d", file, line, tidp, tidp->refCount);
+    osi_Log4(smb_logp,"%s:%d smb_HoldTIDNoLock tidp 0x%p ref %d", file, line, tidp, tidp->refCount);
+#endif
 }
 
+#ifdef DEBUG_SMB_REFCOUNT
+void smb_ReleaseTIDDbg(smb_tid_t *tidp, afs_uint32 locked, char *file, long line)
+#else
 void smb_ReleaseTID(smb_tid_t *tidp, afs_uint32 locked)
+#endif
 {
     smb_tid_t *tp;
     smb_tid_t **ltpp;
-    cm_user_t *userp;
+    cm_user_t *userp = NULL;
+    smb_vc_t  *vcp = NULL;
 
-    userp = NULL;
     if (!locked)
         lock_ObtainWrite(&smb_rctLock);
+    else
+        lock_AssertWrite(&smb_rctLock);
+
     osi_assertx(tidp->refCount-- > 0, "smb_tid_t refCount 0");
-    if (tidp->refCount == 0 && (tidp->deleteOk)) {
-        ltpp = &tidp->vcp->tidsp;
-        for(tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) {
-            if (tp == tidp) 
-                break;
+#ifdef DEBUG_SMB_REFCOUNT
+    afsi_log("%s:%d smb_ReleaseTID tidp 0x%p ref %d deleteOk %d", file, line, tidp, tidp->refCount, tidp->deleteOk);
+    osi_Log5(smb_logp,"%s:%d smb_ReleaseTID tidp 0x%p ref %d deleteOk %d", file, line, tidp, tidp->refCount, tidp->deleteOk);
+#endif
+    if (tidp->refCount == 0) {
+        if (tidp->deleteOk) {
+            ltpp = &tidp->vcp->tidsp;
+            for(tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) {
+                if (tp == tidp) 
+                    break;
+            }
+            osi_assertx(tp != NULL, "null smb_tid_t");
+            *ltpp = tp->nextp;
+            lock_FinalizeMutex(&tidp->mx);
+            userp = tidp->userp;       /* remember to drop ref later */
+            tidp->userp = NULL;
+            vcp = tidp->vcp;
+            tidp->vcp = NULL;
+            free(tidp);
         }
-        osi_assertx(tp != NULL, "null smb_tid_t");
-        *ltpp = tp->nextp;
-        lock_FinalizeMutex(&tidp->mx);
-        userp = tidp->userp;   /* remember to drop ref later */
-        tidp->userp = NULL;
-        smb_ReleaseVCNoLock(tidp->vcp);
-        tidp->vcp = NULL;
     }
     if (!locked)
         lock_ReleaseWrite(&smb_rctLock);
     if (userp)
         cm_ReleaseUser(userp);
+    if (vcp)
+        smb_ReleaseVCNoLock(vcp);
 }              
 
 smb_user_t *smb_FindUID(smb_vc_t *vcp, unsigned short uid, int flags)
@@ -1285,6 +1386,7 @@ void smb_ReleaseUsername(smb_username_t *unp)
 
 void smb_HoldUIDNoLock(smb_user_t *uidp)
 {
+    lock_AssertWrite(&smb_rctLock);
     uidp->refCount++;
 }
 
@@ -1404,7 +1506,11 @@ int smb_SUser(cm_user_t *userp)
  * If the SMB_FLAG_CREATE flag is set, we allocate a new  
  * smb_fid_t data structure if desired File ID cannot be found.
  */
+#ifdef DEBUG_SMB_REFCOUNT
+smb_fid_t *smb_FindFIDDbg(smb_vc_t *vcp, unsigned short fid, int flags, char *file, long line)
+#else
 smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags)
+#endif
 {
     smb_fid_t *fidp;
     int newFid = 0;
@@ -1479,11 +1585,21 @@ smb_fid_t *smb_FindFID(smb_vc_t *vcp, unsigned short fid, int flags)
        }
     }
 
+#ifdef DEBUG_SMB_REFCOUNT
+    if (fidp) {
+        afsi_log("%s:%d smb_FindFID fidp 0x%p ref %d", file, line, fidp, fidp->refCount);
+        osi_Log4(smb_logp,"%s:%d smb_FindFID fidp 0x%p ref %d", file, line, fidp, fidp->refCount);
+    }
+#endif
     lock_ReleaseWrite(&smb_rctLock);
     return fidp;
 }
 
+#ifdef DEBUG_SMB_REFCOUNT
+smb_fid_t *smb_FindFIDByScacheDbg(smb_vc_t *vcp, cm_scache_t * scp, char *file, long line)
+#else
 smb_fid_t *smb_FindFIDByScache(smb_vc_t *vcp, cm_scache_t * scp)
+#endif
 {
     smb_fid_t *fidp = NULL;
     int newFid = 0;
@@ -1498,19 +1614,38 @@ smb_fid_t *smb_FindFIDByScache(smb_vc_t *vcp, cm_scache_t * scp)
             break;
         }
     }
+#ifdef DEBUG_SMB_REFCOUNT
+    if (fidp) {
+        afsi_log("%s:%d smb_FindFIDByScache fidp 0x%p ref %d", file, line, fidp, fidp->refCount);
+        osi_Log4(smb_logp,"%s:%d smb_FindFIDByScache fidp 0x%p ref %d", file, line, fidp, fidp->refCount);
+      }
+#endif
     lock_ReleaseWrite(&smb_rctLock);
     return fidp;
 }
 
+#ifdef DEBUG_SMB_REFCOUNT
+void smb_HoldFIDNoLockDbg(smb_fid_t *fidp, char *file, long line)
+#else
 void smb_HoldFIDNoLock(smb_fid_t *fidp)
+#endif
 {
+    lock_AssertWrite(&smb_rctLock);
     fidp->refCount++;
+#ifdef DEBUG_SMB_REFCOUNT
+    afsi_log("%s:%d smb_HoldFIDNoLock fidp 0x%p ref %d", file, line, fidp, fidp->refCount);
+    osi_Log4(smb_logp,"%s:%d smb_HoldFIDNoLock fidp 0x%p ref %d", file, line, fidp, fidp->refCount);
+#endif
 }
 
 
 /* smb_ReleaseFID cannot be called while an cm_scache_t mutex lock is held */
 /* the sm_fid_t->mx and smb_rctLock must not be held */
+#ifdef DEBUG_SMB_REFCOUNT
+void smb_ReleaseFIDDbg(smb_fid_t *fidp, char *file, long line)
+#else
 void smb_ReleaseFID(smb_fid_t *fidp)
+#endif
 {
     cm_scache_t *scp = NULL;
     cm_user_t *userp = NULL;
@@ -1520,44 +1655,52 @@ void smb_ReleaseFID(smb_fid_t *fidp)
     lock_ObtainMutex(&fidp->mx);
     lock_ObtainWrite(&smb_rctLock);
     osi_assertx(fidp->refCount-- > 0, "smb_fid_t refCount 0");
-    if (fidp->refCount == 0 && (fidp->deleteOk)) {
-        vcp = fidp->vcp;
-        fidp->vcp = NULL;
-        scp = fidp->scp;    /* release after lock is released */
-       if (scp) {
-           lock_ObtainWrite(&scp->rw);
-           scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
-           lock_ReleaseWrite(&scp->rw);
-           osi_Log2(smb_logp,"smb_ReleaseFID fidp 0x%p scp 0x%p", fidp, scp);
-           fidp->scp = NULL;
-       }
-        userp = fidp->userp;
-        fidp->userp = NULL;
+#ifdef DEBUG_SMB_REFCOUNT
+    afsi_log("%s:%d smb_ReleaseFID fidp 0x%p ref %d deleteOk %d", file, line, fidp, fidp->refCount, fidp->deleteOk);
+    osi_Log5(smb_logp,"%s:%d smb_ReleaseFID fidp 0x%p ref %d deleteOk %d", file, line, fidp, fidp->refCount, fidp->deleteOk);
+#endif
+    if (fidp->refCount == 0) {
+        if (fidp->deleteOk) {
+            vcp = fidp->vcp;
+            fidp->vcp = NULL;
+            scp = fidp->scp;    /* release after lock is released */
+            if (scp) {
+                lock_ObtainWrite(&scp->rw);
+                scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
+                lock_ReleaseWrite(&scp->rw);
+                osi_Log2(smb_logp,"smb_ReleaseFID fidp 0x%p scp 0x%p", fidp, scp);
+                fidp->scp = NULL;
+            }
+            userp = fidp->userp;
+            fidp->userp = NULL;
 
-       if (vcp->fidsp) 
-           osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q);
-        thrd_CloseHandle(fidp->raw_write_event);
+            if (vcp->fidsp) 
+                osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q);
+            thrd_CloseHandle(fidp->raw_write_event);
 
-        /* and see if there is ioctl stuff to free */
-        ioctlp = fidp->ioctlp;
-        if (ioctlp) {
-            if (ioctlp->prefix)
+            /* and see if there is ioctl stuff to free */
+            ioctlp = fidp->ioctlp;
+            if (ioctlp) {
+                if (ioctlp->prefix)
                 cm_FreeSpace(ioctlp->prefix);
-            if (ioctlp->ioctl.inAllocp)
-                free(ioctlp->ioctl.inAllocp);
-            if (ioctlp->ioctl.outAllocp)
-                free(ioctlp->ioctl.outAllocp);
-            free(ioctlp);
-        }       
-       lock_ReleaseMutex(&fidp->mx);
-       lock_FinalizeMutex(&fidp->mx);
-        free(fidp);
+                if (ioctlp->ioctl.inAllocp)
+                    free(ioctlp->ioctl.inAllocp);
+                if (ioctlp->ioctl.outAllocp)
+                    free(ioctlp->ioctl.outAllocp);
+                free(ioctlp);
+            }       
+            lock_ReleaseMutex(&fidp->mx);
+            lock_FinalizeMutex(&fidp->mx);
+            free(fidp);
+            fidp = NULL;
 
-       if (vcp)
-           smb_ReleaseVCNoLock(vcp);
-    } else {
-       lock_ReleaseMutex(&fidp->mx);
+            if (vcp)
+                smb_ReleaseVCNoLock(vcp);
+        }
     }
+    if (fidp)
+        lock_ReleaseMutex(&fidp->mx);
+
     lock_ReleaseWrite(&smb_rctLock);
 
     /* now release the scache structure */
@@ -1747,7 +1890,7 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp,
 
         if (cm_ClientStrCmpN(p, cm_mountRootC, cm_mountRootCLen) == 0) {
             p += cm_mountRootCLen;  /* skip mount path */
-            cchlen -= (p - pathName);
+            cchlen -= (DWORD)(p - pathName);
         }
 
         q = p;
@@ -1852,8 +1995,8 @@ int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp,
         if (code == 0) {
             clientchar_t temp[1024];
 
-            cm_FsStringToClientString(ftemp, cm_FsStrLen(ftemp), temp, 1024);
-            cm_ClientStrPrintfN(pathName, lengthof(pathName),
+            cm_FsStringToClientString(ftemp, (int)cm_FsStrLen(ftemp), temp, 1024);
+            cm_ClientStrPrintfN(pathName, (int)lengthof(pathName),
                                 rw ? _C("/.%S/") : _C("/%S/"), temp);
             *pathNamep = cm_ClientStrDup(cm_ClientStrLwr(pathName));
             return 1;
@@ -2121,7 +2264,7 @@ smb_dirSearch_t *smb_NewDirSearch(int isV3)
     return dsp;
 }
 
-static smb_packet_t *GetPacket(void)
+static smb_packet_t *smb_GetPacket(void)
 {
     smb_packet_t *tbp;
 
@@ -2154,7 +2297,7 @@ static smb_packet_t *GetPacket(void)
 smb_packet_t *smb_CopyPacket(smb_packet_t *pkt)
 {
     smb_packet_t *tbp;
-    tbp = GetPacket();
+    tbp = smb_GetPacket();
     memcpy(tbp, pkt, sizeof(smb_packet_t));
     tbp->wctp = tbp->data + (unsigned int)(pkt->wctp - pkt->data);
     tbp->stringsp = NULL;
@@ -2163,7 +2306,7 @@ smb_packet_t *smb_CopyPacket(smb_packet_t *pkt)
     return tbp;
 }
 
-static NCB *GetNCB(void)
+static NCB *smb_GetNCB(void)
 {
     smb_ncb_t *tbp;
     NCB *ncbp;
@@ -2224,7 +2367,7 @@ void smb_FreePacket(smb_packet_t *tbp)
         smb_ReleaseVC(vcp);
 }
 
-static void FreeNCB(NCB *bufferp)
+static void smb_FreeNCB(NCB *bufferp)
 {
     smb_ncb_t *tbp;
         
@@ -2584,7 +2727,7 @@ smb_ParseStringBuf(const unsigned char * bufbase,
         *stringspp = spacep;
 
         cchdest = lengthof(spacep->wdata);
-        cm_Utf8ToUtf16(inp, *pcb_max, spacep->wdata, cchdest);
+        cm_Utf8ToUtf16(inp, (int)*pcb_max, spacep->wdata, cchdest);
 
         return spacep->wdata;
 #ifdef SMB_UNICODE
@@ -2610,7 +2753,7 @@ unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp,
         if (WANTS_UNICODE(pktp) && !(flags & SMB_STRF_FORCEASCII)) {
 
             StringCbLengthW(str, SMB_STRINGBUFSIZE * sizeof(wchar_t), plen);
-            if (!(flags & SMB_STRF_IGNORENULL))
+            if (!(flags & SMB_STRF_IGNORENUL))
                 *plen += sizeof(wchar_t);
 
             return (unsigned char *) 1; /* return TRUE if we are using unicode */
@@ -2620,14 +2763,14 @@ unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp,
         {
             /* Storing ANSI */
 
-            int cch_str;
-            int cch_dest;
+            size_t cch_str;
+            size_t cch_dest;
 
             cch_str = cm_ClientStrLen(str);
-            cch_dest = cm_ClientStringToUtf8(str, cch_str, NULL, 0);
+            cch_dest = cm_ClientStringToUtf8(str, (int)cch_str, NULL, 0);
 
             if (plen)
-                *plen = ((flags & SMB_STRF_IGNORENULL)? cch_dest: cch_dest+1);
+                *plen = ((flags & SMB_STRF_IGNORENUL)? cch_dest: cch_dest+1);
 
             return NULL;
         }
@@ -2645,11 +2788,11 @@ unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp,
 
     */
     if (outp >= pktp->data && outp < pktp->data + sizeof(pktp->data)) {
-        align = ((outp - pktp->data) % 2);
+        align = (int)((outp - pktp->data) % 2);
         buffersize = (pktp->data + sizeof(pktp->data)) - ((char *) outp);
     } else {
-        align = (((size_t) outp) % 2);
-        buffersize = sizeof(pktp->data);
+        align = (int)(((size_t) outp) % 2);
+        buffersize = (int)sizeof(pktp->data);
     }
 
 #ifdef SMB_UNICODE
@@ -2666,12 +2809,12 @@ unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp,
                 return NULL;
 
             *((wchar_t *) outp) = L'\0';
-            if (plen && !(flags & SMB_STRF_IGNORENULL))
+            if (plen && !(flags & SMB_STRF_IGNORENUL))
                 *plen += sizeof(wchar_t);
             return outp + sizeof(wchar_t);
         }
 
-        nchars = cm_ClientStringToUtf16(str, -1, (wchar_t *) outp, buffersize / sizeof(wchar_t));
+        nchars = cm_ClientStringToUtf16(str, -1, (wchar_t *) outp, (int)(buffersize / sizeof(wchar_t)));
         if (nchars == 0) {
             osi_Log2(smb_logp, "UnparseString: Can't convert string to Unicode [%S], GLE=%d",
                      osi_LogSaveClientString(smb_logp, str),
@@ -2680,7 +2823,7 @@ unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp,
         }
 
         if (plen)
-            *plen += sizeof(wchar_t) * ((flags & SMB_STRF_IGNORENULL)? nchars - 1: nchars);
+            *plen += sizeof(wchar_t) * ((flags & SMB_STRF_IGNORENUL)? nchars - 1: nchars);
 
         return outp + sizeof(wchar_t) * nchars;
     }
@@ -2690,10 +2833,10 @@ unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp,
         /* Storing ANSI */
         size_t cch_dest;
 
-        cch_dest = cm_ClientStringToUtf8(str, -1, outp, buffersize);
+        cch_dest = cm_ClientStringToUtf8(str, -1, outp, (int)buffersize);
 
         if (plen)
-            *plen += ((flags & SMB_STRF_IGNORENULL)? cch_dest - 1: cch_dest);
+            *plen += ((flags & SMB_STRF_IGNORENUL)? cch_dest - 1: cch_dest);
 
         return outp + cch_dest;
     }
@@ -2790,7 +2933,7 @@ void smb_SendPacket(smb_vc_t *vcp, smb_packet_t *inp)
         
     ncbp = inp->ncbp;
     if (ncbp == NULL) {
-        ncbp = GetNCB();
+        ncbp = smb_GetNCB();
         localNCB = 1;
     }
  
@@ -2830,7 +2973,7 @@ void smb_SendPacket(smb_vc_t *vcp, smb_packet_t *inp)
     }
 
     if (localNCB)
-        FreeNCB(ncbp);
+        smb_FreeNCB(ncbp);
 }
 
 void smb_MapNTError(long code, unsigned long *NTStatusp)
@@ -3519,7 +3662,7 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
             /* and the faux domain name */
             cm_ClientStringToUtf8(smb_ServerDomainName, -1,
                                   datap + MSV1_0_CHALLENGE_LENGTH,
-                                  sizeof(outp->data)/sizeof(char) - (datap - outp->data));
+                                  (int)(sizeof(outp->data)/sizeof(char) - (datap - outp->data)));
         } else if ( smb_authType == SMB_AUTH_EXTENDED ) {
             void * secBlob;
             int secBlobLength;
@@ -3583,7 +3726,7 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
             /* and the faux domain name */
             cm_ClientStringToUtf8(smb_ServerDomainName, -1,
                                   datap + MSV1_0_CHALLENGE_LENGTH,
-                                  sizeof(outp->data)/sizeof(char) - (datap - outp->data));
+                                  (int)(sizeof(outp->data)/sizeof(char) - (datap - outp->data)));
         } else {
             smb_SetSMBParm(outp, 11, 0); /* encryption key length */
             smb_SetSMBParm(outp, 12, 0); /* resvd */
@@ -3600,7 +3743,7 @@ long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 void smb_CheckVCs(void)
 {
     smb_vc_t * vcp, *nextp;
-    smb_packet_t * outp = GetPacket();
+    smb_packet_t * outp = smb_GetPacket();
     smb_t *smbp;
             
     lock_ObtainWrite(&smb_rctLock);
@@ -3836,7 +3979,7 @@ void smb_WaitingLocksDaemon()
             vcp = wlRequest->vcp;
             inp = wlRequest->inp;
             outp = wlRequest->outp;
-            ncbp = GetNCB();
+            ncbp = smb_GetNCB();
             ncbp->ncb_length = inp->ncb_length;
             inp->spacep = cm_GetSpace();
 
@@ -3860,7 +4003,7 @@ void smb_WaitingLocksDaemon()
             smb_FreePacket(outp);
             smb_ReleaseVC(vcp);
             cm_ReleaseSCache(wlRequest->scp);
-            FreeNCB(ncbp);
+            smb_FreeNCB(ncbp);
             free(wlRequest);
         } while (nwlRequest && smbShutdownFlag == 0);
         thrd_Sleep(1000);
@@ -4128,7 +4271,7 @@ long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t
 }       
 
 static long 
-smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
+smb_ApplyDirListPatches(cm_scache_t * dscp, smb_dirListPatch_t **dirPatchespp,
                         clientchar_t * tidPathp, clientchar_t * relPathp,
                         cm_user_t *userp, cm_req_t *reqp)
 {
@@ -4141,6 +4284,68 @@ smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
     smb_dirListPatch_t *patchp;
     smb_dirListPatch_t *npatchp;
     clientchar_t path[AFSPATHMAX];
+    afs_uint32 rights;
+    afs_int32 mustFake = 0;
+
+    code = cm_FindACLCache(dscp, userp, &rights);
+    if (code == -1) {
+        lock_ObtainWrite(&dscp->rw);
+        code = cm_SyncOp(dscp, NULL, userp, reqp, PRSFS_READ,
+                          CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+        lock_ReleaseWrite(&dscp->rw);
+        if (code == CM_ERROR_NOACCESS) {
+            mustFake = 1;
+            code = 0;
+        }
+    }
+    if (code)
+        goto cleanup;
+
+    if (!mustFake) {    /* Bulk Stat */
+        afs_uint32 count;
+        cm_bulkStat_t *bsp = malloc(sizeof(cm_bulkStat_t));
+
+        memset(bsp, 0, sizeof(cm_bulkStat_t));
+
+        for (patchp = *dirPatchespp, count=0; 
+             patchp; 
+             patchp = (smb_dirListPatch_t *) osi_QNext(&patchp->q)) {
+            cm_scache_t *tscp = cm_FindSCache(&patchp->fid);
+            int i;
+
+            if (tscp) {
+                if (lock_TryWrite(&tscp->rw)) {
+                    /* we have an entry that we can look at */
+                    if (!(tscp->flags & CM_SCACHEFLAG_EACCESS) && cm_HaveCallback(tscp)) {
+                        /* we have a callback on it.  Don't bother
+                        * fetching this stat entry, since we're happy
+                        * with the info we have.
+                        */
+                        lock_ReleaseWrite(&tscp->rw);
+                        cm_ReleaseSCache(tscp);
+                        continue;
+                    }
+                    lock_ReleaseWrite(&tscp->rw);
+                } /* got lock */
+                cm_ReleaseSCache(tscp);
+            }  /* found entry */
+
+            i = bsp->counter++;
+            bsp->fids[i].Volume = patchp->fid.volume;
+            bsp->fids[i].Vnode = patchp->fid.vnode;
+            bsp->fids[i].Unique = patchp->fid.unique;
+
+            if (bsp->counter == AFSCBMAX) {
+                code = cm_TryBulkStatRPC(dscp, bsp, userp, reqp);
+                memset(bsp, 0, sizeof(cm_bulkStat_t));
+            }
+        }
+
+        if (bsp->counter > 0)
+            code = cm_TryBulkStatRPC(dscp, bsp, userp, reqp);
+
+        free(bsp);
+    }
 
     for (patchp = *dirPatchespp; patchp; patchp =
          (smb_dirListPatch_t *) osi_QNext(&patchp->q)) {
@@ -4161,42 +4366,74 @@ smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
             continue;
         }
         lock_ObtainWrite(&scp->rw);
-        code = cm_SyncOp(scp, NULL, userp, reqp, 0,
-                          CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-        if (code) {    
+        if (mustFake || (scp->flags & CM_SCACHEFLAG_EACCESS) || !cm_HaveCallback(scp)) {
             lock_ReleaseWrite(&scp->rw);
-            cm_ReleaseSCache(scp);
-            if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE)
-                *dptr++ = SMB_ATTR_HIDDEN;
-            continue;
-        }
 
-       cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+            /* set the attribute */
+            switch (scp->fileType) {
+            case CM_SCACHETYPE_DIRECTORY:
+            case CM_SCACHETYPE_MOUNTPOINT:
+            case CM_SCACHETYPE_SYMLINK:
+            case CM_SCACHETYPE_INVALID:
+                attr = SMB_ATTR_DIRECTORY;
+                break;
+            default:
+                /* if we get here we either have a normal file
+                * or we have a file for which we have never 
+                * received status info.  In this case, we can
+                * check the even/odd value of the entry's vnode.
+                * even means it is to be treated as a directory
+                * and odd means it is to be treated as a file.
+                */
+                if (mustFake && (scp->fid.vnode & 0x1))
+                    attr = SMB_ATTR_DIRECTORY;
+                else
+                    attr = SMB_ATTR_NORMAL;
+            }
+            *dptr++ = attr;
+
+            /* 1969-12-31 23:59:58 +00*/
+            dosTime = 0xEBBFBF7D;
+
+            /* copy out time */
+            shortTemp = (unsigned short) (dosTime & 0xffff);
+            *((u_short *)dptr) = shortTemp;
+            dptr += 2;
 
-        lock_ConvertWToR(&scp->rw);
-        attr = smb_Attributes(scp);
-        /* check hidden attribute (the flag is only ON when dot file hiding is on ) */
-        if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE)
-            attr |= SMB_ATTR_HIDDEN;
-        *dptr++ = attr;
+            /* and copy out date */
+            shortTemp = (unsigned short) ((dosTime>>16) & 0xffff);
+            *((u_short *)dptr) = shortTemp;
+            dptr += 2;
+                
+            /* copy out file length */
+            *((u_long *)dptr) = 0;
+            dptr += 4;
+        } else {
+            lock_ConvertWToR(&scp->rw);
+            attr = smb_Attributes(scp);
+            /* check hidden attribute (the flag is only ON when dot file hiding is on ) */
+            if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE)
+                attr |= SMB_ATTR_HIDDEN;
+            *dptr++ = attr;
 
-        /* get dos time */
-        smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
+            /* get dos time */
+            smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
                 
-        /* copy out time */
-        shortTemp = (unsigned short) (dosTime & 0xffff);
-        *((u_short *)dptr) = shortTemp;
-        dptr += 2;
-
-        /* and copy out date */
-        shortTemp = (unsigned short) ((dosTime>>16) & 0xffff);
-        *((u_short *)dptr) = shortTemp;
-        dptr += 2;
+            /* copy out time */
+            shortTemp = (unsigned short) (dosTime & 0xffff);
+            *((u_short *)dptr) = shortTemp;
+            dptr += 2;
+
+            /* and copy out date */
+            shortTemp = (unsigned short) ((dosTime>>16) & 0xffff);
+            *((u_short *)dptr) = shortTemp;
+            dptr += 2;
                 
-        /* copy out file length */
-        *((u_long *)dptr) = scp->length.LowPart;
-        dptr += 4;
-        lock_ReleaseRead(&scp->rw);
+            /* copy out file length */
+            *((u_long *)dptr) = scp->length.LowPart;
+            dptr += 4;
+            lock_ReleaseRead(&scp->rw);
+        }
         cm_ReleaseSCache(scp);
     }
         
@@ -4209,6 +4446,7 @@ smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
     /* and mark the list as empty */
     *dirPatchespp = NULL;
 
+  cleanup:
     return code;
 }
 
@@ -4391,12 +4629,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
              */
             cm_HoldSCache(scp);
             lock_ObtainWrite(&scp->rw);
-            if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0
-                 && LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) {
-                scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
-                dsp->flags |= SMB_DIRSEARCH_BULKST;
-               dsp->scp->bulkStatProgress = hzero;
-            }
+            dsp->flags |= SMB_DIRSEARCH_BULKST;
             lock_ReleaseWrite(&scp->rw);
         }
     }
@@ -4499,25 +4732,10 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
             /* now, if we're doing a star match, do bulk fetching of all of 
              * the status info for files in the dir.
              */
-            if (starPattern) {
-                smb_ApplyDirListPatches(&dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
-                lock_ObtainWrite(&scp->rw);
-                if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
-                     LargeIntegerGreaterThanOrEqualTo(thyper, 
-                                                      scp->bulkStatProgress)) {
-                    /* Don't bulk stat if risking timeout */
-                    int now = GetTickCount();
-                    if (now - req.startTime > RDRtimeout * 1000) {
-                        scp->bulkStatProgress = thyper;
-                        scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
-                        dsp->flags &= ~SMB_DIRSEARCH_BULKST;
-                       dsp->scp->bulkStatProgress = hzero;
-                    } else
-                        code = cm_TryBulkStat(scp, &thyper, userp, &req);
-                }
-            } else {
-                lock_ObtainWrite(&scp->rw);
-            }
+            if (starPattern)
+                smb_ApplyDirListPatches(scp, &dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
+
+            lock_ObtainWrite(&scp->rw);
             lock_ReleaseMutex(&dsp->mx);
             if (code) {
                 osi_Log2(smb_logp, "SMB search dir buf_Get scp %x failed %d", scp, code);
@@ -4720,7 +4938,7 @@ long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *ou
     /* apply and free last set of patches; if not doing a star match, this
      * will be empty, but better safe (and freeing everything) than sorry.
      */
-    smb_ApplyDirListPatches(&dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
+    smb_ApplyDirListPatches(scp, &dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
 
     /* special return code for unsuccessful search */
     if (code == 0 && dataLength < 21 && returnedNames == 0)
@@ -6787,15 +7005,7 @@ long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char
 
         /* now copy the data */
        memcpy(bufferp->datap + bufIndex, op, nbytes);
-        buf_SetDirty(bufferp, bufIndex, nbytes);
-
-        /* and record the last writer */
-        if (bufferp->userp != userp) {
-            cm_HoldUser(userp);
-            if (bufferp->userp) 
-                cm_ReleaseUser(bufferp->userp);
-            bufferp->userp = userp;
-        }
+        buf_SetDirty(bufferp, bufIndex, nbytes, userp);
 
         /* adjust counters, pointers, etc. */
         op += nbytes;
@@ -8168,8 +8378,8 @@ void smb_Server(VOID *parmp)
 
     rx_StartClientThread();
 
-    outncbp = GetNCB();
-    outbufp = GetPacket();
+    outncbp = smb_GetNCB();
+    outbufp = smb_GetPacket();
     outbufp->ncbp = outncbp;
 
     while (1) {
@@ -8259,12 +8469,12 @@ void smb_Server(VOID *parmp)
                    lock_ObtainWrite(&smb_globalLock);
                    dead_sessions[vcp->session] = TRUE;
                    lock_ReleaseWrite(&smb_globalLock);
-                   smb_CleanupDeadVC(vcp);
-                   smb_ReleaseVC(vcp);
-                   vcp = NULL;
                 } else {
                    lock_ReleaseMutex(&vcp->mx);
                }
+                smb_CleanupDeadVC(vcp);
+                smb_ReleaseVC(vcp);
+                vcp = NULL;
             }
             goto doneWithNCB;
 
@@ -8291,31 +8501,33 @@ void smb_Server(VOID *parmp)
         default:
             /* A weird error code.  Log it, sleep, and continue. */
             vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
-           if (vcp) 
+           if (vcp) {
                lock_ObtainMutex(&vcp->mx);
-            if (vcp && vcp->errorCount++ > 3) {
-                osi_Log2(smb_logp, "session [ %d ] closed, vcp->errorCount = %d", idx_session, vcp->errorCount);
-               if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
-                   osi_Log2(smb_logp, "marking dead vcp 0x%x, user struct 0x%x",
-                            vcp, vcp->usersp);
-                   vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
-                   lock_ReleaseMutex(&vcp->mx);
-                   lock_ObtainWrite(&smb_globalLock);
-                   dead_sessions[vcp->session] = TRUE;
-                   lock_ReleaseWrite(&smb_globalLock);
-                   smb_CleanupDeadVC(vcp);
-                   smb_ReleaseVC(vcp);
-                   vcp = NULL;
-               } else {
-                   lock_ReleaseMutex(&vcp->mx);
-               }
-               goto doneWithNCB;
-            }
-            else {
-               if (vcp)
+                if (vcp->errorCount++ > 3) {
+                    osi_Log2(smb_logp, "session [ %d ] closed, vcp->errorCount = %d", idx_session, vcp->errorCount);
+                    if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+                        osi_Log2(smb_logp, "marking dead vcp 0x%x, user struct 0x%x",
+                                 vcp, vcp->usersp);
+                        vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+                        lock_ReleaseMutex(&vcp->mx);
+                        lock_ObtainWrite(&smb_globalLock);
+                        dead_sessions[vcp->session] = TRUE;
+                        lock_ReleaseWrite(&smb_globalLock);
+                    } else {
+                        lock_ReleaseMutex(&vcp->mx);
+                    }
+                    smb_CleanupDeadVC(vcp);
+                    smb_ReleaseVC(vcp);
+                    vcp = NULL;
+                    goto doneWithNCB;
+                }
+                else {
                    lock_ReleaseMutex(&vcp->mx);
-                thrd_Sleep(1000);
-               thrd_SetEvent(SessionEvents[idx_session]);
+                    smb_ReleaseVC(vcp);
+                    vcp = NULL;
+                    Sleep(10);
+                    thrd_SetEvent(SessionEvents[idx_session]);
+                }
             }
            continue;
         }
@@ -8424,6 +8636,10 @@ void smb_Server(VOID *parmp)
     }
     if (vcp)
         smb_ReleaseVC(vcp);
+    if (outbufp)
+        smb_FreePacket(outbufp);
+    if (outncbp)
+        smb_FreeNCB(outncbp);
 }
 
 /*
@@ -8458,7 +8674,7 @@ void InitNCBslot(int idx)
 
     osi_assertx( idx < (sizeof(NCBs) / sizeof(NCBs[0])), "invalid index" );
 
-    NCBs[idx] = GetNCB();
+    NCBs[idx] = smb_GetNCB();
     sprintf(eventName,"NCBavails[%d]", idx);
     NCBavails[idx] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName);
     if ( GetLastError() == ERROR_ALREADY_EXISTS )
@@ -8473,7 +8689,7 @@ void InitNCBslot(int idx)
         osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
     for (i=0; i<smb_NumServerThreads; i++)
         NCBreturns[i][idx] = retHandle;
-    bufp = GetPacket();
+    bufp = smb_GetPacket();
     bufp->spacep = cm_GetSpace();
     bufs[idx] = bufp;
 }
@@ -8499,7 +8715,7 @@ void smb_Listener(void *parmp)
     if ( GetLastError() == ERROR_ALREADY_EXISTS )
         thrd_ResetEvent(ListenerShutdown[lana]);
 
-    ncbp = GetNCB();
+    ncbp = smb_GetNCB();
 
     /* retrieve computer name */
     GetComputerName(cname, &cnamelen);
@@ -8681,7 +8897,7 @@ void smb_Listener(void *parmp)
 
         if (session >= SESSION_MAX - 1  || numNCBs >= NCB_MAX - 1) {
             unsigned long code = CM_ERROR_ALLBUSY;
-            smb_packet_t * outp = GetPacket();
+            smb_packet_t * outp = smb_GetPacket();
             unsigned char *outWctp;
             smb_t *smbp;
             
@@ -8782,7 +8998,7 @@ void smb_Listener(void *parmp)
     }  /* dispatch while loop */
 
 exit_thread:
-    FreeNCB(ncbp);
+    smb_FreeNCB(ncbp);
     thrd_SetEvent(ListenerShutdown[lana]);
     return;
 }
@@ -8841,7 +9057,7 @@ void smb_LanAdapterChange(int locked) {
              strcmp(cm_NetbiosName, NetbiosName) ) {
             change = 1;
         } else {
-            NCB *ncbp = GetNCB();
+            NCB *ncbp = smb_GetNCB();
             ncbp->ncb_command = NCBENUM;
             ncbp->ncb_buffer = (PUCHAR)&temp_list;
             ncbp->ncb_length = sizeof(temp_list);
@@ -8858,7 +9074,7 @@ void smb_LanAdapterChange(int locked) {
                     }
                 }
             }
-           FreeNCB(ncbp);
+           smb_FreeNCB(ncbp);
         }
     } 
 
@@ -8893,7 +9109,7 @@ int smb_NetbiosInit(int locked)
         return 0;
     }
     /* setup the NCB system */
-    ncbp = GetNCB();
+    ncbp = smb_GetNCB();
 
     /* Call lanahelper to get Netbios name, lan adapter number and gateway flag */
     if (SUCCEEDED(code = lana_GetUncServerNameEx(cm_NetbiosName, &lanaNum, &isGateway, LANA_NETBIOS_NAME_FULL))) {
@@ -9045,7 +9261,7 @@ int smb_NetbiosInit(int locked)
     }
         
     /* we're done with the NCB now */
-    FreeNCB(ncbp);
+    smb_FreeNCB(ncbp);
 
     afsi_log("smb_NetbiosInit smb_LANadapter=%d",smb_LANadapter);
     if (lana_list.length > 0)
@@ -9165,7 +9381,7 @@ void smb_StopListeners(int locked)
 #endif
                                   );
 
-    ncbp = GetNCB();
+    ncbp = smb_GetNCB();
 
     /* Unregister the SMB name */
     for (l = 0; l < lana_list.length; l++) {
@@ -9182,7 +9398,7 @@ void smb_StopListeners(int locked)
     /* force a re-evaluation of the network adapters */
     lana_list.length = 0;
     smb_LANadapter = LANA_INVALID;
-    FreeNCB(ncbp);
+    smb_FreeNCB(ncbp);
     if (!locked)
         lock_ReleaseMutex(&smb_StartedLock);
 }
@@ -9564,7 +9780,7 @@ void smb_Shutdown(void)
     /*fprintf(stderr, "Entering smb_Shutdown\n");*/
         
     /* setup the NCB system */
-    ncbp = GetNCB();
+    ncbp = smb_GetNCB();
 
     /* Block new sessions by setting shutdown flag */
     smbShutdownFlag = 1;
@@ -9665,7 +9881,7 @@ void smb_Shutdown(void)
         }
     }
     lock_ReleaseWrite(&smb_rctLock);
-    FreeNCB(ncbp);
+    smb_FreeNCB(ncbp);
     TlsFree(smb_TlsRequestSlot);
 }
 
@@ -9673,7 +9889,7 @@ void smb_Shutdown(void)
 char *smb_GetSharename()
 {
     char *name;
-    int len;
+    size_t len;
 
     /* Make sure we have been properly initialized. */
     if (smb_localNamep == NULL)
@@ -9757,37 +9973,119 @@ void smb_LogPacket(smb_packet_t *packet)
 int smb_DumpVCP(FILE *outputFile, char *cookie, int lock)
 {
     int zilch;
-    char output[1024];
+    char output[4196];
   
     smb_vc_t *vcp;
-  
+    smb_username_t *unp;
+    smb_waitingLockRequest_t *wlrp;
+
     if (lock)
         lock_ObtainRead(&smb_rctLock);
   
+    sprintf(output, "begin dumping smb_username_t\r\n");
+    WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+    for (unp = usernamesp; unp; unp=unp->nextp) 
+    {
+        cm_ucell_t *ucellp;
+
+        sprintf(output, "%s -- smb_unp=0x%p, refCount=%d, cm_userp=0x%p, flags=0x%x, logoff=%u, name=%S, machine=%S\r\n", 
+                cookie, unp, unp->refCount, unp->userp, unp->flags, unp->last_logoff_t,
+                unp->name ? unp->name : _C("NULL"), 
+                unp->machine ? unp->machine : _C("NULL"));
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+        sprintf(output, "  begin dumping cm_ucell_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+        for ( ucellp = unp->userp->cellInfop; ucellp; ucellp = ucellp->nextp ) {
+            sprintf(output, "  %s -- ucellp=0x%p, cellp=0x%p, flags=0x%x, tktLen=%04u, kvno=%03u, expires=%I64u, gen=%d, name=%s, cellname=%s\r\n", 
+                     cookie, ucellp, ucellp->cellp, ucellp->flags, ucellp->ticketLen, ucellp->kvno, 
+                     ucellp->expirationTime, ucellp->gen, 
+                     ucellp->userName,
+                     ucellp->cellp->name);
+            WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        }
+
+        sprintf(output, "  done dumping cm_ucell_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+    }
+    sprintf(output, "done dumping smb_username_t\r\n");
+    WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+
+    sprintf(output, "begin dumping smb_waitingLockRequest_t\r\n");
+    WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+
+    for ( wlrp = smb_allWaitingLocks; wlrp; wlrp = (smb_waitingLockRequest_t *) osi_QNext(&wlrp->q)) {
+        smb_waitingLock_t *lockp;
+
+        sprintf(output, "%s wlrp=0x%p vcp=0x%p, scp=0x%p, type=0x%x, start_t=0x%I64u msTimeout=0x%x\r\n",
+                 cookie, wlrp, wlrp->vcp, wlrp->scp, wlrp->lockType, wlrp->start_t, wlrp->msTimeout);
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+      
+        sprintf(output, "  begin dumping smb_waitingLock_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        for (lockp = wlrp->locks; lockp; lockp = (smb_waitingLock_t *) osi_QNext(&lockp->q)) {
+            sprintf(output, "  %s -- waitlockp=0x%p lockp=0x%p key=0x%I64x offset=0x%I64x length=0x%I64x state=0x%x\r\n", 
+                    cookie, lockp, lockp->lockp, lockp->key, lockp->LOffset.QuadPart, lockp->LLength.QuadPart, lockp->state);
+            WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        }
+        sprintf(output, "  done dumping smb_waitingLock_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+    }
+
+    sprintf(output, "done dumping smb_waitingLockRequest_t\r\n");
+    WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
     sprintf(output, "begin dumping smb_vc_t\r\n");
     WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
 
     for (vcp = smb_allVCsp; vcp; vcp=vcp->nextp) 
     {
         smb_fid_t *fidp;
+        smb_tid_t *tidp;
+        smb_user_t *userp;
       
-        sprintf(output, "%s vcp=0x%p, refCount=%d, flags=%d, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\r\n",
+        sprintf(output, "%s vcp=0x%p, refCount=%d, flags=0x%x, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\r\n",
                  cookie, vcp, vcp->refCount, vcp->flags, vcp->vcID, vcp->lsn, vcp->uidCounter, vcp->tidCounter, vcp->fidCounter);
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
       
-        sprintf(output, "begin dumping smb_fid_t\r\n");
+        sprintf(output, "  begin dumping smb_user_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        for (userp = vcp->usersp; userp; userp = userp->nextp) {
+            sprintf(output, "  %s -- smb_userp=0x%p, refCount=%d, uid=%d, vcp=0x%p, unp=0x%p, flags=0x%x, delOk=%d\r\n", 
+                    cookie, userp, userp->refCount, userp->userID, userp->vcp, userp->unp, userp->flags, userp->deleteOk);
+            WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        }
+        sprintf(output, "  done dumping smb_user_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+        sprintf(output, "  begin dumping smb_tid_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        for (tidp = vcp->tidsp; tidp; tidp = tidp->nextp) {
+            sprintf(output, "  %s -- smb_tidp=0x%p, refCount=%d, tid=%d, vcp=0x%p, cm_userp=0x%p, flags=0x%x, delOk=%d, path=%S\r\n", 
+                    cookie, tidp, tidp->refCount, tidp->tid, tidp->vcp, tidp->userp, tidp->flags, tidp->deleteOk,
+                    tidp->pathname ? tidp->pathname : _C("NULL"));
+            WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        }
+        sprintf(output, "  done dumping smb_tid_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+        sprintf(output, "  begin dumping smb_fid_t\r\n");
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
 
         for (fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q))
         {
-            sprintf(output, "%s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, ioctlp=0x%p, NTopen_pathp=%s, NTopen_wholepathp=%s\r\n", 
-                     cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->ioctlp, 
+            sprintf(output, "  %s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, userp=0x%p, ioctlp=0x%p, flags=0x%x, delOk=%d, NTopen_pathp=%S, NTopen_wholepathp=%S\r\n", 
+                    cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->userp, fidp->ioctlp, fidp->flags, fidp->deleteOk,
                     fidp->NTopen_pathp ? fidp->NTopen_pathp : _C("NULL"), 
                     fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : _C("NULL"));
             WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
         }
       
-        sprintf(output, "done dumping smb_fid_t\r\n");
+        sprintf(output, "  done dumping smb_fid_t\r\n");
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
     }
 
@@ -9800,24 +10098,47 @@ int smb_DumpVCP(FILE *outputFile, char *cookie, int lock)
     for (vcp = smb_deadVCsp; vcp; vcp=vcp->nextp) 
     {
         smb_fid_t *fidp;
-      
-        sprintf(output, "%s vcp=0x%p, refCount=%d, flags=%d, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\r\n",
-                 cookie, vcp, vcp->refCount, vcp->flags, vcp->vcID, vcp->lsn, vcp->uidCounter, vcp->tidCounter, vcp->fidCounter);
+        smb_tid_t *tidp;
+        smb_user_t *userp;
+
+        sprintf(output, "%s vcp=0x%p, refCount=%d, flags=0x%x, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\r\n",
+                cookie, vcp, vcp->refCount, vcp->flags, vcp->vcID, vcp->lsn, vcp->uidCounter, vcp->tidCounter, vcp->fidCounter);
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
       
-        sprintf(output, "begin dumping smb_fid_t\r\n");
+        sprintf(output, "  begin dumping smb_user_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        for (userp = vcp->usersp; userp; userp = userp->nextp) {
+            sprintf(output, "  %s -- smb_userp=0x%p, refCount=%d, uid=%d, vcp=0x%p, unp=0x%p, flags=0x%x, delOk=%d\r\n", 
+                    cookie, userp, userp->refCount, userp->userID, userp->vcp, userp->unp, userp->flags, userp->deleteOk);
+            WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        }
+        sprintf(output, "  done dumping smb_user_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+        sprintf(output, "  begin dumping smb_tid_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        for (tidp = vcp->tidsp; tidp; tidp = tidp->nextp) {
+            sprintf(output, "  %s -- smb_tidp=0x%p, refCount=%d, tid=%d, vcp=0x%p, cm_userp=0x%p, flags=0x%x, delOk=%d, path=%S\r\n", 
+                    cookie, tidp, tidp->refCount, tidp->tid, tidp->vcp, tidp->userp, tidp->flags, tidp->deleteOk,
+                    tidp->pathname ? tidp->pathname : _C("NULL"));
+            WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+        }
+        sprintf(output, "  done dumping smb_tid_t\r\n");
+        WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+        sprintf(output, "  begin dumping smb_fid_t\r\n");
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
 
         for (fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q))
         {
-            sprintf(output, "%s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, ioctlp=0x%p, NTopen_pathp=%s, NTopen_wholepathp=%s\r\n", 
-                     cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->ioctlp, 
+            sprintf(output, "  %s -- smb_fidp=0x%p, refCount=%d, fid=%d, vcp=0x%p, scp=0x%p, userp=0x%p, ioctlp=0x%p, flags=0x%x, delOk=%d, NTopen_pathp=%S, NTopen_wholepathp=%S\r\n", 
+                    cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->userp, fidp->ioctlp, fidp->flags, fidp->deleteOk,
                     fidp->NTopen_pathp ? fidp->NTopen_pathp : _C("NULL"), 
                     fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : _C("NULL"));
             WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
         }
       
-        sprintf(output, "done dumping smb_fid_t\r\n");
+        sprintf(output, "  done dumping smb_fid_t\r\n");
         WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
     }