static char *illegalChars = "\\/:*?\"<>|";
BOOL isWindows2000 = FALSE;
-smb_vc_t *dead_vcp = NULL;
smb_vc_t *active_vcp = NULL;
-/* TODO; logout mechanism needs to be thread-safe */
-char *loggedOutName = NULL;
-smb_user_t *loggedOutUserp = NULL;
-time_t loggedOutTime;
-int loggedOut = 0;
int smbShutdownFlag = 0;
int smb_LogoffTokenTransfer;
ULONG smb_lsaSecPackage;
LSA_STRING smb_lsaLogonOrigin;
-#define NCBmax MAXIMUM_WAIT_OBJECTS
-EVENT_HANDLE NCBavails[NCBmax], NCBevents[NCBmax];
+#define NCB_MAX MAXIMUM_WAIT_OBJECTS
+EVENT_HANDLE NCBavails[NCB_MAX], NCBevents[NCB_MAX];
EVENT_HANDLE **NCBreturns;
EVENT_HANDLE **NCBShutdown;
EVENT_HANDLE *smb_ServerShutdown;
-DWORD NCBsessions[NCBmax];
-NCB *NCBs[NCBmax];
-struct smb_packet *bufs[NCBmax];
-
-#define Sessionmax MAXIMUM_WAIT_OBJECTS - 4
-EVENT_HANDLE SessionEvents[Sessionmax];
-unsigned short LSNs[Sessionmax];
-int lanas[Sessionmax];
-BOOL dead_sessions[Sessionmax];
+DWORD NCBsessions[NCB_MAX];
+NCB *NCBs[NCB_MAX];
+struct smb_packet *bufs[NCB_MAX];
+
+#define SESSION_MAX MAXIMUM_WAIT_OBJECTS - 4
+EVENT_HANDLE SessionEvents[SESSION_MAX];
+unsigned short LSNs[SESSION_MAX];
+int lanas[SESSION_MAX];
+BOOL dead_sessions[SESSION_MAX];
LANA_ENUM lana_list;
/* for raw I/O */
char *smb_localNamep = NULL;
smb_vc_t *smb_allVCsp;
+smb_vc_t *smb_deadVCsp;
smb_username_t *usernamesp = NULL;
/* forward decl */
void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp,
- NCB *ncbp, raw_write_cont_t *rwcp);
+ NCB *ncbp, raw_write_cont_t *rwcp);
void smb_NetbiosInit();
#ifdef DJGPP
#ifndef AFS_WIN95_ENV
/* Faux server GUID. This is never checked. */
GUID smb_ServerGUID = { 0x40015cb8, 0x058a, 0x44fc, { 0xae, 0x7e, 0xbb, 0x29, 0x52, 0xee, 0x7e, 0xff }};
+const char * ncb_error_string(int code)
+{
+ const char * s;
+ switch ( code ) {
+ case 0x01: s = "llegal buffer length"; break;
+ case 0x03: s = "illegal command"; break;
+ case 0x05: s = "command timed out"; break;
+ case 0x06: s = "message incomplete, issue another command"; break;
+ case 0x07: s = "illegal buffer address"; break;
+ case 0x08: s = "session number out of range"; break;
+ case 0x09: s = "no resource available"; break;
+ case 0x0a: s = "session closed"; break;
+ case 0x0b: s = "command cancelled"; break;
+ case 0x0d: s = "duplicate name"; break;
+ case 0x0e: s = "name table full"; break;
+ case 0x0f: s = "no deletions, name has active sessions"; break;
+ case 0x11: s = "local session table full"; break;
+ case 0x12: s = "remote session table full"; break;
+ case 0x13: s = "illegal name number"; break;
+ case 0x14: s = "no callname"; break;
+ case 0x15: s = "cannot put * in NCB_NAME"; break;
+ case 0x16: s = "name in use on remote adapter"; break;
+ case 0x17: s = "name deleted"; break;
+ case 0x18: s = "session ended abnormally"; break;
+ case 0x19: s = "name conflict detected"; break;
+ case 0x21: s = "interface busy, IRET before retrying"; break;
+ case 0x22: s = "too many commands outstanding, retry later";break;
+ case 0x23: s = "ncb_lana_num field invalid"; break;
+ case 0x24: s = "command completed while cancel occurring "; break;
+ case 0x26: s = "command not valid to cancel"; break;
+ case 0x30: s = "name defined by anther local process"; break;
+ case 0x34: s = "environment undefined. RESET required"; break;
+ case 0x35: s = "required OS resources exhausted"; break;
+ case 0x36: s = "max number of applications exceeded"; break;
+ case 0x37: s = "no saps available for netbios"; break;
+ case 0x38: s = "requested resources are not available"; break;
+ case 0x39: s = "invalid ncb address or length > segment"; break;
+ case 0x3B: s = "invalid NCB DDID"; break;
+ case 0x3C: s = "lock of user area failed"; break;
+ case 0x3f: s = "NETBIOS not loaded"; break;
+ case 0x40: s = "system error"; break;
+ default: s = "unknown error";
+ }
+ return s;
+}
+
+
char * myCrt_Dispatch(int i)
{
switch (i)
struct tm localJunk;
time_t t = unixTime;
- ltp = localtime((time_t*) &t);
+ ltp = localtime(&t);
/* if we fail, make up something */
if (!ltp) {
if (!vcp && (flags & SMB_FLAG_CREATE)) {
vcp = malloc(sizeof(*vcp));
memset(vcp, 0, sizeof(*vcp));
- vcp->vcID = numVCs++;
- vcp->refCount = 1;
+ lock_ObtainWrite(&smb_globalLock);
+ vcp->vcID = ++numVCs;
+ lock_ReleaseWrite(&smb_globalLock);
+ vcp->refCount = 2; /* smb_allVCsp and caller */
vcp->tidCounter = 1;
vcp->fidCounter = 1;
- vcp->uidCounter = 1; /* UID 0 is reserved for blank user */
+ vcp->uidCounter = 1; /* UID 0 is reserved for blank user */
vcp->nextp = smb_allVCsp;
smb_allVCsp = vcp;
lock_InitializeMutex(&vcp->mx, "vc_t mutex");
memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH);
if (numVCs >= CM_SESSION_RESERVED) {
+ lock_ObtainWrite(&smb_globalLock);
numVCs = 0;
+ lock_ReleaseWrite(&smb_globalLock);
osi_Log0(smb_logp, "WARNING: numVCs wrapping around");
}
}
for(i=0; i<11; i++) {
tc = *maskp++;
- if (tc == '?' || tc == '*' || tc == '>') return 1;
+ if (tc == '?' || tc == '*' || tc == '>')
+ return 1;
}
return 0;
}
-void smb_ReleaseVCNoLock(smb_vc_t *vcp)
+void smb_ReleaseVCInternal(smb_vc_t *vcp)
{
- osi_Log2(smb_logp,"smb_ReleaseVCNoLock vcp %x ref %d",vcp, vcp->refCount);
+ smb_vc_t **vcpp;
+
#ifdef DEBUG
osi_assert(vcp->refCount-- != 0);
#else
vcp->refCount--;
#endif
+
+ if (vcp->refCount == 0) {
+ /* remove VCP from smb_deadVCsp */
+ for (vcpp = &smb_deadVCsp; *vcpp; vcpp = &((*vcpp)->nextp)) {
+ if (*vcpp == vcp) {
+ *vcpp = vcp->nextp;
+ break;
+ }
+ }
+ lock_FinalizeMutex(&vcp->mx);
+ memset(vcp,0,sizeof(smb_vc_t));
+ free(vcp);
+ }
+}
+
+void smb_ReleaseVCNoLock(smb_vc_t *vcp)
+{
+ osi_Log2(smb_logp,"smb_ReleaseVCNoLock vcp %x ref %d",vcp, vcp->refCount);
+ smb_ReleaseVCInternal(vcp);
}
void smb_ReleaseVC(smb_vc_t *vcp)
{
lock_ObtainWrite(&smb_rctLock);
osi_Log2(smb_logp,"smb_ReleaseVC vcp %x ref %d",vcp, vcp->refCount);
-#ifdef DEBUG
- osi_assert(vcp->refCount-- != 0);
-#else
- vcp->refCount--;
-#endif
+ smb_ReleaseVCInternal(vcp);
lock_ReleaseWrite(&smb_rctLock);
}
{
smb_fid_t *fidpIter;
smb_fid_t *fidpNext;
- smb_fid_t *fidp;
unsigned short fid;
smb_tid_t *tidpIter;
smb_tid_t *tidpNext;
- smb_tid_t *tidp;
unsigned short tid;
- smb_user_t *userpIter;
- smb_user_t *userpNext;
- smb_user_t *userp;
- unsigned short uid;
+ smb_user_t *uidpIter;
+ smb_user_t *uidpNext;
+ smb_vc_t **vcpp;
osi_Log1(smb_logp, "Cleaning up dead vcp 0x%x", vcp);
- lock_ObtainRead(&smb_rctLock);
+ lock_ObtainWrite(&smb_rctLock);
for (fidpIter = vcp->fidsp; fidpIter; fidpIter = fidpNext) {
fidpNext = (smb_fid_t *) osi_QNext(&fidpIter->q);
- if (fidpIter->flags & SMB_FID_DELETE)
+ if (fidpIter->delete)
continue;
fid = fidpIter->fid;
osi_Log2(smb_logp, " Cleanup FID %d (fidp=0x%x)", fid, fidpIter);
- lock_ReleaseRead(&smb_rctLock);
- fidp = smb_FindFID(vcp, fid, 0);
- osi_assert(fidp);
- smb_CloseFID(vcp, fidp, NULL, 0);
- smb_ReleaseFID(fidp);
+ smb_HoldFIDNoLock(fidpIter);
+ lock_ReleaseWrite(&smb_rctLock);
- lock_ObtainRead(&smb_rctLock);
+ smb_CloseFID(vcp, fidpIter, NULL, 0);
+ smb_ReleaseFID(fidpIter);
+
+ lock_ObtainWrite(&smb_rctLock);
+ fidpNext = vcp->fidsp;
}
for (tidpIter = vcp->tidsp; tidpIter; tidpIter = tidpNext) {
tidpNext = tidpIter->nextp;
- if (tidpIter->flags & SMB_TIDFLAG_DELETE)
+ if (tidpIter->delete)
continue;
+ tidpIter->delete = 1;
tid = tidpIter->tid;
osi_Log2(smb_logp, " Cleanup TID %d (tidp=0x%x)", tid, tidpIter);
- lock_ReleaseRead(&smb_rctLock);
- tidp = smb_FindTID(vcp, tid, 0);
- osi_assert(tidp);
+ smb_HoldTIDNoLock(tidpIter);
+ lock_ReleaseWrite(&smb_rctLock);
- lock_ObtainMutex(&tidp->mx);
- tidp->flags |= SMB_TIDFLAG_DELETE;
- lock_ReleaseMutex(&tidp->mx);
+ smb_ReleaseTID(tidpIter);
- smb_ReleaseTID(tidp);
-
- lock_ObtainRead(&smb_rctLock);
+ lock_ObtainWrite(&smb_rctLock);
+ tidpNext = vcp->tidsp;
}
- for (userpIter = vcp->usersp; userpIter; userpIter = userpNext) {
- userpNext = userpIter->nextp;
-
- if (userpIter->flags & SMB_USERFLAG_DELETE)
+ for (uidpIter = vcp->usersp; uidpIter; uidpIter = uidpNext) {
+ uidpNext = uidpIter->nextp;
+ if (uidpIter->delete)
continue;
-
- uid = userpIter->userID;
- osi_Log2(smb_logp, " Cleanup UID %d (userp=0x%x)", uid, userpIter);
- lock_ReleaseRead(&smb_rctLock);
-
- userp = smb_FindUID(vcp, uid, 0);
- osi_assert(userp);
-
- lock_ObtainMutex(&userp->mx);
- userp->flags |= SMB_USERFLAG_DELETE;
- lock_ReleaseMutex(&userp->mx);
-
- smb_ReleaseUID(userp);
-
- lock_ObtainRead(&smb_rctLock);
- }
-
- lock_ReleaseRead(&smb_rctLock);
-
- osi_Log0(smb_logp, "Done cleaning up dead vcp");
+ uidpIter->delete = 1;
+
+ /* do not add an additional reference count for the smb_user_t
+ * as the smb_vc_t already is holding a reference */
+ lock_ReleaseWrite(&smb_rctLock);
+
+ smb_ReleaseUID(uidpIter);
+
+ lock_ObtainWrite(&smb_rctLock);
+ uidpNext = vcp->usersp;
+ }
+
+ /* remove VCP from smb_allVCsp */
+ for (vcpp = &smb_allVCsp; *vcpp; vcpp = &((*vcpp)->nextp)) {
+ if (*vcpp == vcp) {
+ *vcpp = vcp->nextp;
+ vcp->nextp = smb_deadVCsp;
+ smb_deadVCsp = vcp;
+ /* We intentionally do not keep a reference to the
+ * vcp once it is placed on the deadVCsp list. This
+ * allows the refcount to reach 0 so we can delete
+ * it. */
+ smb_ReleaseVCNoLock(vcp);
+ break;
+ }
+ }
+ lock_ReleaseWrite(&smb_rctLock);
+ osi_Log1(smb_logp, "Finished cleaning up dead vcp 0x%x", vcp);
}
smb_tid_t *smb_FindTID(smb_vc_t *vcp, unsigned short tid, int flags)
return tidp;
}
+void smb_HoldTIDNoLock(smb_tid_t *tidp)
+{
+ tidp->refCount++;
+}
+
void smb_ReleaseTID(smb_tid_t *tidp)
{
smb_tid_t *tp;
userp = NULL;
lock_ObtainWrite(&smb_rctLock);
osi_assert(tidp->refCount-- > 0);
- if (tidp->refCount == 0 && (tidp->flags & SMB_TIDFLAG_DELETE)) {
+ if (tidp->refCount == 0 && (tidp->delete)) {
ltpp = &tidp->vcp->tidsp;
for(tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) {
if (tp == tidp)
userp = tidp->userp; /* remember to drop ref later */
tidp->userp = NULL;
smb_ReleaseVCNoLock(tidp->vcp);
- tidp->vcp = 0;
+ tidp->vcp = NULL;
}
lock_ReleaseWrite(&smb_rctLock);
if (userp)
uidp = malloc(sizeof(*uidp));
memset(uidp, 0, sizeof(*uidp));
uidp->nextp = vcp->usersp;
- uidp->refCount = 1;
+ uidp->refCount = 2; /* one for the vcp and one for the caller */
uidp->vcp = vcp;
smb_HoldVCNoLock(vcp);
vcp->usersp = uidp;
return uidp;
}
-smb_username_t *smb_FindUserByName(char *usern, char *machine, int flags)
+smb_username_t *smb_FindUserByName(char *usern, char *machine, afs_uint32 flags)
{
smb_username_t *unp= NULL;
unp->machine = strdup(machine);
usernamesp = unp;
lock_InitializeMutex(&unp->mx, "username_t mutex");
+ if (flags & SMB_FLAG_AFSLOGON)
+ unp->flags = SMB_USERNAMEFLAG_AFSLOGON;
}
+
lock_ReleaseWrite(&smb_rctLock);
return unp;
}
lock_ReleaseWrite(&smb_rctLock);
return uidp;
}
+
+void smb_ReleaseUsername(smb_username_t *unp)
+{
+ smb_username_t *up;
+ smb_username_t **lupp;
+ cm_user_t *userp = NULL;
+ time_t now = osi_Time();
+
+ lock_ObtainWrite(&smb_rctLock);
+ osi_assert(unp->refCount-- > 0);
+ if (unp->refCount == 0 && !(unp->flags & SMB_USERNAMEFLAG_AFSLOGON) &&
+ (unp->flags & SMB_USERNAMEFLAG_LOGOFF)) {
+ lupp = &usernamesp;
+ for(up = *lupp; up; lupp = &up->nextp, up = *lupp) {
+ if (up == unp)
+ break;
+ }
+ osi_assert(up != NULL);
+ *lupp = up->nextp;
+ up->nextp = NULL; /* do not remove this */
+ lock_FinalizeMutex(&unp->mx);
+ userp = unp->userp;
+ free(unp->name);
+ free(unp->machine);
+ free(unp);
+ }
+ lock_ReleaseWrite(&smb_rctLock);
+
+ if (userp) {
+ cm_ReleaseUser(userp);
+ }
+}
+
+void smb_HoldUIDNoLock(smb_user_t *uidp)
+{
+ uidp->refCount++;
+}
+
void smb_ReleaseUID(smb_user_t *uidp)
{
smb_user_t *up;
smb_user_t **lupp;
- cm_user_t *userp;
+ smb_username_t *unp = NULL;
- userp = NULL;
lock_ObtainWrite(&smb_rctLock);
osi_assert(uidp->refCount-- > 0);
- if (uidp->refCount == 0 && (uidp->flags & SMB_USERFLAG_DELETE)) {
+ if (uidp->refCount == 0) {
lupp = &uidp->vcp->usersp;
for(up = *lupp; up; lupp = &up->nextp, up = *lupp) {
if (up == uidp)
osi_assert(up != NULL);
*lupp = up->nextp;
lock_FinalizeMutex(&uidp->mx);
- if (uidp->unp) {
- userp = uidp->unp->userp; /* avoid deadlock by releasing */
- uidp->unp->userp = NULL; /* after releasing the lock */
- }
+ unp = uidp->unp;
smb_ReleaseVCNoLock(uidp->vcp);
- uidp->vcp = NULL;
+ uidp->vcp = NULL;
+ free(uidp);
}
lock_ReleaseWrite(&smb_rctLock);
- if (userp) {
- cm_ReleaseUserVCRef(userp);
- cm_ReleaseUser(userp);
- }
+
+ if (unp) {
+ if (unp->userp)
+ cm_ReleaseUserVCRef(unp->userp);
+ smb_ReleaseUsername(unp);
+ }
}
+cm_user_t *smb_GetUserFromUID(smb_user_t *uidp)
+{
+ cm_user_t *up = NULL;
+
+ if (!uidp)
+ return NULL;
+
+ lock_ObtainMutex(&uidp->mx);
+ if (uidp->unp) {
+ up = uidp->unp->userp;
+ cm_HoldUser(up);
+ }
+ lock_ReleaseMutex(&uidp->mx);
+
+ return up;
+}
+
/* retrieve a held reference to a user structure corresponding to an incoming
* request.
* corresponding release function is cm_ReleaseUser.
*/
-cm_user_t *smb_GetUser(smb_vc_t *vcp, smb_packet_t *inp)
+cm_user_t *smb_GetUserFromVCP(smb_vc_t *vcp, smb_packet_t *inp)
{
smb_user_t *uidp;
- cm_user_t *up;
+ cm_user_t *up = NULL;
smb_t *smbp;
smbp = (smb_t *) inp;
uidp = smb_FindUID(vcp, smbp->uid, 0);
- if ((!uidp) || (!uidp->unp))
- return NULL;
-
- lock_ObtainMutex(&uidp->mx);
- up = uidp->unp->userp;
- cm_HoldUser(up);
- lock_ReleaseMutex(&uidp->mx);
+ if (!uidp)
+ return NULL;
+
+ up = smb_GetUserFromUID(uidp);
smb_ReleaseUID(uidp);
-
return up;
}
if (fid == fidp->fid) {
if (newFid) {
fid++;
- if (fid == 0) {
+ if (fid == 0xFFFF) {
osi_Log1(smb_logp,
"New FID number wraps on vcp 0x%x", vcp);
fid = 1;
osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
thrd_CloseHandle(event);
fid++;
- if (fid == 0) {
+ if (fid == 0xFFFF) {
osi_Log1(smb_logp, "New FID wraps around for vcp 0x%x", vcp);
fid = 1;
}
fidp->raw_write_event = event;
if (newFid) {
vcp->fidCounter = fid+1;
- if (vcp->fidCounter == 0) {
- osi_Log1(smb_logp, "fidCounter wrapped around for vcp 0x%x",
- vcp);
+ if (vcp->fidCounter == 0xFFFF) {
+ osi_Log1(smb_logp, "fidCounter wrapped around for vcp 0x%x",
+ vcp);
vcp->fidCounter = 1;
- }
- }
+ }
+ }
}
lock_ReleaseWrite(&smb_rctLock);
return fidp;
}
+void smb_HoldFIDNoLock(smb_fid_t *fidp)
+{
+ fidp->refCount++;
+}
+
void smb_ReleaseFID(smb_fid_t *fidp)
{
- cm_scache_t *scp;
- cm_user_t *userp;
+ cm_scache_t *scp = NULL;
+ cm_user_t *userp = NULL;
smb_vc_t *vcp = NULL;
smb_ioctl_t *ioctlp;
- if (!fidp)
- return;
-
- scp = NULL;
- userp = NULL;
lock_ObtainWrite(&smb_rctLock);
osi_assert(fidp->refCount-- > 0);
- if (fidp->refCount == 0 && (fidp->flags & SMB_FID_DELETE)) {
+ lock_ObtainMutex(&fidp->mx);
+ if (fidp->refCount == 0 && (fidp->delete)) {
vcp = fidp->vcp;
fidp->vcp = NULL;
scp = fidp->scp; /* release after lock is released */
userp = fidp->userp;
fidp->userp = NULL;
- osi_QRemove((osi_queue_t **) &vcp->fidsp, &fidp->q);
+ 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 */
free(ioctlp->outAllocp);
free(ioctlp);
}
-
+ lock_ReleaseMutex(&fidp->mx);
+ lock_FinalizeMutex(&fidp->mx);
free(fidp);
- smb_ReleaseVCNoLock(vcp);
+ if (vcp)
+ smb_ReleaseVCNoLock(vcp);
+ } else {
+ lock_ReleaseMutex(&fidp->mx);
}
lock_ReleaseWrite(&smb_rctLock);
*/
if (tp->refCount == 0 && (isV3 || tp->cookie <= 255)) {
/* hold and delete */
+ lock_ObtainMutex(&tp->mx);
tp->flags |= SMB_DIRSEARCH_DELETE;
+ lock_ReleaseMutex(&tp->mx);
victimsp[victimCount++] = tp;
tp->refCount++;
}
#endif /* !DJGPP */
if (code != 0) {
- char * s;
- switch ( code ) {
- case 0x01: s = "llegal buffer length "; break;
- case 0x03: s = "illegal command "; break;
- case 0x05: s = "command timed out "; break;
- case 0x06: s = "message incomplete, issue another command"; break;
- case 0x07: s = "illegal buffer address "; break;
- case 0x08: s = "session number out of range "; break;
- case 0x09: s = "no resource available "; break;
- case 0x0a: s = "session closed "; break;
- case 0x0b: s = "command cancelled "; break;
- case 0x0d: s = "duplicate name "; break;
- case 0x0e: s = "name table full "; break;
- case 0x0f: s = "no deletions, name has active sessions "; break;
- case 0x11: s = "local session table full "; break;
- case 0x12: s = "remote session table full "; break;
- case 0x13: s = "illegal name number "; break;
- case 0x14: s = "no callname "; break;
- case 0x15: s = "cannot put * in NCB_NAME "; break;
- case 0x16: s = "name in use on remote adapter "; break;
- case 0x17: s = "name deleted "; break;
- case 0x18: s = "session ended abnormally "; break;
- case 0x19: s = "name conflict detected "; break;
- case 0x21: s = "interface busy, IRET before retrying "; break;
- case 0x22: s = "too many commands outstanding, retry later"; break;
- case 0x23: s = "ncb_lana_num field invalid "; break;
- case 0x24: s = "command completed while cancel occurring "; break;
- case 0x26: s = "command not valid to cancel "; break;
- case 0x30: s = "name defined by anther local process "; break;
- case 0x34: s = "environment undefined. RESET required "; break;
- case 0x35: s = "required OS resources exhausted "; break;
- case 0x36: s = "max number of applications exceeded "; break;
- case 0x37: s = "no saps available for netbios "; break;
- case 0x38: s = "requested resources are not available "; break;
- case 0x39: s = "invalid ncb address or length > segment "; break;
- case 0x3B: s = "invalid NCB DDID "; break;
- case 0x3C: s = "lock of user area failed "; break;
- case 0x3f: s = "NETBIOS not loaded "; break;
- case 0x40: s = "system error "; break;
- default:
- s = "unknown error";
- }
+ const char * s = ncb_error_string(code);
osi_Log2(smb_logp, "SendPacket failure code %d \"%s\"", code, s);
+#ifndef DJGPP
+ LogEvent(EVENTLOG_WARNING_TYPE, MSG_SMB_SEND_PACKET_FAILURE, s);
+#endif /* !DJGPP */
+
+ osi_Log2(smb_logp, "marking dead vcp 0x%x, user struct 0x%x",
+ vcp, vcp->usersp);
+
+ lock_ObtainMutex(&vcp->mx);
+ 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);
}
if (localNCB)
if (!rawBuf)
goto send1a;
+ lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL)
{
+ lock_ReleaseMutex(&fidp->mx);
#ifndef DJGPP
rc = smb_IoctlReadRaw(fidp, vcp, inp, outp);
#else
smb_ReleaseFID(fidp);
return rc;
}
-
- userp = smb_GetUser(vcp, inp);
+ lock_ReleaseMutex(&fidp->mx);
+
+ userp = smb_GetUserFromVCP(vcp, inp);
#ifndef DJGPP
code = smb_ReadData(fidp, &offset, count, rawBuf, userp, &finalCount);
osi_Log1(smb_logp, "SMB receive negotiate; %d + 1 ongoing ops",
ongoingOps - 1);
- if (!isGateway) {
- if (active_vcp) {
- DWORD now = GetCurrentTime();
- if (now - last_msg_time >= 30000
- && now - last_msg_time <= 90000) {
- osi_Log1(smb_logp,
- "Setting dead_vcp %x", active_vcp);
- if (dead_vcp) {
- smb_ReleaseVC(dead_vcp);
- osi_Log1(smb_logp,
- "Previous dead_vcp %x", dead_vcp);
- }
- smb_HoldVC(active_vcp);
- dead_vcp = active_vcp;
- dead_vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
- }
- }
- }
-
- inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK;
namep = smb_GetSMBData(inp, &dbytes);
namex = 0;
tcounter++; /* which proto entry we're looking at */
}
+ lock_ObtainMutex(&vcp->mx);
if (NTProtoIndex != -1) {
protoIndex = NTProtoIndex;
vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3);
vcp->flags |= SMB_VCFLAG_USECORE;
}
else protoIndex = -1;
+ lock_ReleaseMutex(&vcp->mx);
if (protoIndex == -1)
return CM_ERROR_INVAL;
return 0;
}
+void smb_CheckVCs(void)
+{
+ smb_vc_t * vcp, *nextp;
+ smb_packet_t * outp = GetPacket();
+ smb_t *smbp;
+
+ lock_ObtainWrite(&smb_rctLock);
+ for ( vcp=smb_allVCsp, nextp=NULL; vcp; vcp = nextp )
+ {
+ nextp = vcp->nextp;
+
+ if (vcp->flags & SMB_VCFLAG_ALREADYDEAD)
+ continue;
+
+ smb_HoldVCNoLock(vcp);
+ if (nextp)
+ smb_HoldVCNoLock(nextp);
+ smb_FormatResponsePacket(vcp, NULL, outp);
+ smbp = (smb_t *)outp;
+ outp->inCom = smbp->com = 0x2b /* Echo */;
+ smbp->tid = 0xFFFF;
+ smbp->pid = 0;
+ smbp->uid = 0;
+ smbp->mid = 0;
+ smbp->res[0] = 0;
+ smbp->res[1] = 0;
+
+ smb_SetSMBParm(outp, 0, 0);
+ smb_SetSMBDataLength(outp, 0);
+ lock_ReleaseWrite(&smb_rctLock);
+
+ smb_SendPacket(vcp, outp);
+
+ lock_ObtainWrite(&smb_rctLock);
+ smb_ReleaseVCNoLock(vcp);
+ if (nextp)
+ smb_ReleaseVCNoLock(nextp);
+ }
+ lock_ReleaseWrite(&smb_rctLock);
+ smb_FreePacket(outp);
+}
+
void smb_Daemon(void *parmp)
{
afs_uint32 count = 0;
+ smb_username_t **unpp;
+ time_t now;
while(smbShutdownFlag == 0) {
count++;
if ( smb_localZero != old_localZero )
cm_noteLocalMountPointChange();
#endif
- }
+
+ smb_CheckVCs();
+ }
+
+ /* GC smb_username_t objects that will no longer be used */
+ now = osi_Time();
+ lock_ObtainWrite(&smb_rctLock);
+ for ( unpp=&usernamesp; *unpp; ) {
+ int delete = 0;
+ smb_username_t *unp;
+
+ lock_ObtainMutex(&(*unpp)->mx);
+ if ( (*unpp)->refCount > 0 ||
+ ((*unpp)->flags & SMB_USERNAMEFLAG_AFSLOGON) ||
+ !((*unpp)->flags & SMB_USERNAMEFLAG_LOGOFF))
+ ;
+ else if (!smb_LogoffTokenTransfer ||
+ ((*unpp)->last_logoff_t + smb_LogoffTransferTimeout < now))
+ delete = 1;
+ lock_ReleaseMutex(&(*unpp)->mx);
+
+ if (delete) {
+ cm_user_t * userp;
+
+ unp = *unpp;
+ *unpp = unp->nextp;
+ unp->nextp = NULL;
+ lock_FinalizeMutex(&unp->mx);
+ userp = unp->userp;
+ free(unp->name);
+ free(unp->machine);
+ free(unp);
+ if (userp) {
+ lock_ReleaseWrite(&smb_rctLock);
+ cm_ReleaseUser(userp);
+ lock_ObtainWrite(&smb_rctLock);
+ }
+ } else {
+ unpp = &(*unpp)->nextp;
+ }
+ }
+ lock_ReleaseWrite(&smb_rctLock);
+
/* XXX GC dir search entries */
}
}
return CM_ERROR_BADSMB;
strcpy(shareName, tp+1);
- userp = smb_GetUser(vcp, inp);
-
lock_ObtainMutex(&vcp->mx);
newTid = vcp->tidCounter++;
lock_ReleaseMutex(&vcp->mx);
tidp = smb_FindTID(vcp, newTid, SMB_FLAG_CREATE);
uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+ userp = smb_GetUserFromUID(uidp);
shareFound = smb_FindShare(vcp, uidp, shareName, &sharePath);
if (uidp)
smb_ReleaseUID(uidp);
osi_Log3(smb_logp, "SMB search dir cookie 0x%x, connection %d, attr 0x%x",
nextCookie, dsp->cookie, attribute);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
/* try to get the vnode for the path name next */
lock_ObtainMutex(&dsp->mx);
LargeIntegerGreaterThanOrEqualTo(thyper,
scp->bulkStatProgress)) {
/* Don't bulk stat if risking timeout */
- int now = GetCurrentTime();
+ int now = GetTickCount();
if (now - req.startTime > 5000) {
scp->bulkStatProgress = thyper;
scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
rootScp = cm_data.rootSCachep;
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
caseFold = CM_FLAG_CASEFOLD;
rootScp = cm_data.rootSCachep;
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
caseFold = CM_FLAG_CASEFOLD;
rootScp = cm_data.rootSCachep;
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
/* we shouldn't need this for V3 requests, but we seem to */
caseFold = CM_FLAG_CASEFOLD;
/* find the tree and free it */
tidp = smb_FindTID(vcp, ((smb_t *)inp)->tid, 0);
if (tidp) {
- lock_ObtainMutex(&tidp->mx);
- tidp->flags |= SMB_TIDFLAG_DELETE;
- lock_ReleaseMutex(&tidp->mx);
+ lock_ObtainWrite(&smb_rctLock);
+ tidp->delete = 1;
+ lock_ReleaseWrite(&smb_rctLock);
smb_ReleaseTID(tidp);
}
return 0;
}
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
caseFold = CM_FLAG_CASEFOLD;
cm_HoldUser(userp);
fidp->userp = userp;
+ lock_ObtainMutex(&fidp->mx);
if ((share & 0xf) == 0)
fidp->flags |= SMB_FID_OPENREAD;
else if ((share & 0xf) == 1)
fidp->flags |= SMB_FID_OPENWRITE;
else
fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
+ lock_ReleaseMutex(&fidp->mx);
lock_ObtainMutex(&scp->mx);
smb_SetSMBParm(outp, 0, fidp->fid);
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, pathp);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD;
DWORD filter;
cm_req_t req;
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
if (code) {
cm_ReleaseUser(userp);
DWORD filter;
cm_req_t req;
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
if (code) {
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, pathp);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
caseFold = CM_FLAG_CASEFOLD;
fid = smb_ChainFID(fid, inp);
fidp = smb_FindFID(vcp, fid, 0);
- if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
- if (fidp)
- smb_ReleaseFID(fidp);
+ if (!fidp)
+ return CM_ERROR_BADFD;
+
+ lock_ObtainMutex(&fidp->mx);
+ if (fidp->flags & SMB_FID_IOCTL) {
+ lock_ReleaseMutex(&fidp->mx);
+ smb_ReleaseFID(fidp);
return CM_ERROR_BADFD;
}
+ lock_ReleaseMutex(&fidp->mx);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_OPENWRITE)
afs_uint32 dosTime) {
long code = 0;
cm_req_t req;
+ cm_scache_t *dscp = fidp->NTopen_dscp;
+ char *pathp = fidp->NTopen_pathp;
osi_Log3(smb_logp, "smb_CloseFID Closing fidp 0x%x (fid=%d vcp=0x%x)",
fidp, fidp->fid, vcp);
if (!userp) {
- if (!fidp->userp) {
+ lock_ObtainMutex(&fidp->mx);
+ if (!fidp->userp && !(fidp->flags & SMB_FID_IOCTL)) {
+ lock_ReleaseMutex(&fidp->mx);
osi_Log0(smb_logp, " No user specified. Not closing fid");
- return CM_ERROR_BADFD;
- }
+ return CM_ERROR_BADFD;
+ }
userp = fidp->userp; /* no hold required since fidp is held
throughout the function */
+ lock_ReleaseMutex(&fidp->mx);
}
cm_InitReq(&req);
- lock_ObtainMutex(&fidp->mx);
+ lock_ObtainWrite(&smb_rctLock);
+ if (fidp->delete) {
+ osi_Log0(smb_logp, " Fid already closed.");
+ lock_ReleaseWrite(&smb_rctLock);
+ return CM_ERROR_BADFD;
+ }
+ fidp->delete = 1;
+ lock_ReleaseWrite(&smb_rctLock);
+ lock_ObtainMutex(&fidp->mx);
/* Don't jump the gun on an async raw write */
while (fidp->raw_writers) {
lock_ReleaseMutex(&fidp->mx);
lock_ObtainMutex(&fidp->mx);
}
- fidp->flags |= SMB_FID_DELETE;
-
/* watch for ioctl closes, and read-only opens */
if (fidp->scp != NULL &&
(fidp->flags & (SMB_FID_OPENWRITE | SMB_FID_DELONCLOSE))
}
if (fidp->flags & SMB_FID_DELONCLOSE) {
- cm_scache_t *dscp = fidp->NTopen_dscp;
- char *pathp = fidp->NTopen_pathp;
char *fullPathp;
smb_FullName(dscp, fidp->scp, pathp, &fullPathp, userp, &req);
dscp, fullPathp, NULL, TRUE);
}
free(fullPathp);
+ fidp->flags &= ~SMB_FID_DELONCLOSE;
}
- lock_ReleaseMutex(&fidp->mx);
if (fidp->flags & SMB_FID_NTOPEN) {
- cm_ReleaseSCache(fidp->NTopen_dscp);
- free(fidp->NTopen_pathp);
+ fidp->NTopen_dscp = NULL;
fidp->NTopen_pathp = NULL;
+ fidp->flags &= ~SMB_FID_NTOPEN;
}
if (fidp->NTopen_wholepathp) {
free(fidp->NTopen_wholepathp);
fidp->NTopen_wholepathp = NULL;
}
+ lock_ReleaseMutex(&fidp->mx);
+
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+
+ if (pathp)
+ free(pathp);
return code;
}
return CM_ERROR_BADFD;
}
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
code = smb_CloseFID(vcp, fidp, userp, dosTime);
/* make sure we have a writable FD */
if (!(fidp->flags & SMB_FID_OPENWRITE)) {
+ lock_ReleaseMutex(&fidp->mx);
code = CM_ERROR_BADFDOP;
goto done;
}
/* handle over quota or out of space */
if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) {
*writtenp = written;
- code = CM_ERROR_QUOTA;
+ code = (scp->flags & CM_SCACHEFLAG_OVERQUOTA) ? CM_ERROR_QUOTA : CM_ERROR_SPACE;
break;
}
done:
lock_ReleaseMutex(&scp->mx);
- lock_ReleaseMutex(&fidp->mx);
+
if (bufferp) {
lock_ReleaseMutex(&bufferp->mx);
buf_Release(bufferp);
fidp->NTopen_dscp, fidp->NTopen_pathp,
NULL, TRUE);
}
+ lock_ReleaseMutex(&fidp->mx);
if (code == 0 && doWriteBack) {
long code2;
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
- if (!fidp) {
+ if (!fidp)
return CM_ERROR_BADFD;
- }
-
- if (fidp->flags & SMB_FID_IOCTL)
- return smb_IoctlWrite(fidp, vcp, inp, outp);
- userp = smb_GetUser(vcp, inp);
+ lock_ObtainMutex(&fidp->mx);
+ if (fidp->flags & SMB_FID_IOCTL) {
+ lock_ReleaseMutex(&fidp->mx);
+ code = smb_IoctlWrite(fidp, vcp, inp, outp);
+ smb_ReleaseFID(fidp);
+ return code;
+ }
+ lock_ReleaseMutex(&fidp->mx);
+ userp = smb_GetUserFromVCP(vcp, inp);
/* special case: 0 bytes transferred means truncate to this position */
if (count == 0) {
truncAttr.length.HighPart = 0;
lock_ObtainMutex(&fidp->mx);
code = cm_SetAttr(fidp->scp, &truncAttr, userp, &req);
+ fidp->flags |= SMB_FID_LENGTHSETDONE;
lock_ReleaseMutex(&fidp->mx);
smb_SetSMBParm(outp, 0, /* count */ 0);
smb_SetSMBDataLength(outp, 0);
- fidp->flags |= SMB_FID_LENGTHSETDONE;
goto done;
}
* and don't set client mod time if we think that would go against the
* intention.
*/
+ lock_ObtainMutex(&fidp->mx);
if ((fidp->flags & SMB_FID_MTIMESETDONE) != SMB_FID_MTIMESETDONE) {
fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME;
fidp->scp->clientModTime = time(NULL);
}
+ lock_ReleaseMutex(&fidp->mx);
code = 0;
while ( code == 0 && count > 0 ) {
osi_Log2(smb_logp, "Completing Raw Write offset %x count %x",
rwcp->offset.LowPart, rwcp->count);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
#ifndef DJGPP
rawBuf = rwcp->buf;
}
}
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
/*
* Work around bug in NT client
* and don't set client mod time if we think that would go against the
* intention.
*/
+ lock_ObtainMutex(&fidp->mx);
if ((fidp->flags & SMB_FID_LOOKSLIKECOPY) != SMB_FID_LOOKSLIKECOPY) {
fidp->scp->mask |= CM_SCACHEMASK_CLIENTMODTIME;
fidp->scp->clientModTime = time(NULL);
}
+ lock_ReleaseMutex(&fidp->mx);
code = 0;
while ( code == 0 && count > 0 ) {
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
- if (!fidp) {
+ if (!fidp)
return CM_ERROR_BADFD;
- }
+ lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL) {
- return smb_IoctlRead(fidp, vcp, inp, outp);
+ lock_ReleaseMutex(&fidp->mx);
+ code = smb_IoctlRead(fidp, vcp, inp, outp);
+ smb_ReleaseFID(fidp);
+ return code;
}
+ lock_ReleaseMutex(&fidp->mx);
{
LARGE_INTEGER LOffset, LLength;
return code;
}
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
/* remember this for final results */
smb_SetSMBParm(outp, 0, count);
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, pathp);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
caseFold = CM_FLAG_CASEFOLD;
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, pathp);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
caseFold = CM_FLAG_CASEFOLD;
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
osi_assert(fidp);
+ cm_HoldUser(userp);
+
+ lock_ObtainMutex(&fidp->mx);
+ /* always create it open for read/write */
+ fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
+
/* save a pointer to the vnode */
fidp->scp = scp;
/* and the user */
- cm_HoldUser(userp);
fidp->userp = userp;
-
- /* always create it open for read/write */
- fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
+ lock_ReleaseMutex(&fidp->mx);
- smb_ReleaseFID(fidp);
-
smb_SetSMBParm(outp, 0, fidp->fid);
smb_SetSMBDataLength(outp, 0);
cm_Open(scp, 0, userp);
+ smb_ReleaseFID(fidp);
cm_ReleaseUser(userp);
/* leave scp held since we put it in fidp->scp */
return 0;
/* try to find the file descriptor */
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
- if (!fidp || (fidp->flags & SMB_FID_IOCTL)) {
+
+ if (!fidp)
+ return CM_ERROR_BADFD;
+
+ lock_ObtainMutex(&fidp->mx);
+ if (fidp->flags & SMB_FID_IOCTL) {
+ lock_ReleaseMutex(&fidp->mx);
+ smb_ReleaseFID(fidp);
return CM_ERROR_BADFD;
}
+ lock_ReleaseMutex(&fidp->mx);
- userp = smb_GetUser(vcp, inp);
+ userp = smb_GetUserFromVCP(vcp, inp);
lock_ObtainMutex(&fidp->mx);
scp = fidp->scp;
/* Remember session generation number and time */
oldGen = sessionGen;
- oldTime = GetCurrentTime();
+ oldTime = GetTickCount();
while (inp->inCom != 0xff) {
dp = &smb_dispatchTable[inp->inCom];
if (inp->inCom == 0x1d)
/* Raw Write */
- code = smb_ReceiveCoreWriteRaw (vcp, inp, outp,
- rwcp);
+ code = smb_ReceiveCoreWriteRaw (vcp, inp, outp, rwcp);
else {
osi_Log4(smb_logp,"Dispatch %s vcp 0x%p lana %d lsn %d",myCrt_Dispatch(inp->inCom),vcp,vcp->lana,vcp->lsn);
code = (*(dp->procp)) (vcp, inp, outp);
}
if (oldGen != sessionGen) {
- newTime = GetCurrentTime();
+ newTime = GetTickCount();
#ifndef DJGPP
LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_WRONG_SESSION,
newTime - oldTime, ncbp->ncb_length);
outWctp = tp;
} /* while loop over all requests in the packet */
- /* done logging out, turn off logging-out flag */
- if (!(inp->flags & SMB_PACKETFLAG_PROFILE_UPDATE_OK)) {
- vcp->justLoggedOut = NULL;
- if (loggedOut) {
- loggedOut = 0;
- free(loggedOutName);
- loggedOutName = NULL;
- smb_ReleaseUID(loggedOutUserp);
- loggedOutUserp = NULL;
- }
- }
-
/* now send the output packet, and return */
if (!noSend)
smb_SendPacket(vcp, outp);
if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
if (active_vcp != vcp) {
if (active_vcp) {
- smb_ReleaseVC(active_vcp);
osi_Log2(smb_logp,
"Replacing active_vcp %x with %x", active_vcp, vcp);
+ smb_ReleaseVC(active_vcp);
}
smb_HoldVC(vcp);
+ lock_ObtainWrite(&smb_globalLock);
active_vcp = vcp;
+ lock_ReleaseWrite(&smb_globalLock);
}
- last_msg_time = GetCurrentTime();
- } else if (active_vcp == vcp) {
+ last_msg_time = GetTickCount();
+ } else if (active_vcp == vcp) { /* the vcp is dead */
smb_ReleaseVC(active_vcp);
+ lock_ObtainWrite(&smb_globalLock);
active_vcp = NULL;
+ lock_ReleaseWrite(&smb_globalLock);
}
-
return;
}
outbufp->ncbp = outncbp;
while (1) {
+ if (vcp) {
+ smb_ReleaseVC(vcp);
+ vcp = NULL;
+ }
code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBreturns[myIdx],
FALSE, INFINITE);
idx_session = NCBsessions[idx_NCB];
rc = ncbp->ncb_retcode;
- if (rc != NRC_PENDING && rc != NRC_GOODRET) {
- switch (rc) {
- case 0x01:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal buffer length", ncbp->ncb_lsn, idx_session);
- break;
- case 0x03:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal command", ncbp->ncb_lsn, idx_session);
- break;
- case 0x05:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: command timed out", ncbp->ncb_lsn, idx_session);
- break;
- case 0x06:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: message incomplete, issue another command", ncbp->ncb_lsn, idx_session);
- break;
- case 0x07:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal buffer address", ncbp->ncb_lsn, idx_session);
- break;
- case 0x08:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session number out of range", ncbp->ncb_lsn, idx_session);
- break;
- case 0x09:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no resource available", ncbp->ncb_lsn, idx_session);
- break;
- case 0x0a:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session closed", ncbp->ncb_lsn, idx_session);
- break;
- case 0x0b:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: command cancelled", ncbp->ncb_lsn, idx_session);
- break;
- case 0x0d:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: duplicate name", ncbp->ncb_lsn, idx_session);
- break;
- case 0x0e:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name table full", ncbp->ncb_lsn, idx_session);
- break;
- case 0x0f:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no deletions, name has active lsn %d sessions", ncbp->ncb_lsn, idx_session);
- break;
- case 0x11:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: local session table full", ncbp->ncb_lsn, idx_session);
- break;
- case 0x12:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: remote session table full", ncbp->ncb_lsn, idx_session);
- break;
- case 0x13:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: illegal name number", ncbp->ncb_lsn, idx_session);
- break;
- case 0x14:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no callname", ncbp->ncb_lsn, idx_session);
- break;
- case 0x15:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: cannot put * in NCB_NAME", ncbp->ncb_lsn, idx_session);
- break;
- case 0x16:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name in use on remote adapter", ncbp->ncb_lsn, idx_session);
- break;
- case 0x17:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name deleted", ncbp->ncb_lsn, idx_session);
- break;
- case 0x18:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: session ended abnormally", ncbp->ncb_lsn, idx_session);
- break;
- case 0x19:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name conflict detected", ncbp->ncb_lsn, idx_session);
- break;
- case 0x21:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: interface busy, IRET before retrying", ncbp->ncb_lsn, idx_session);
- break;
- case 0x22:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: too many commands outstanding, retry later", ncbp->ncb_lsn, idx_session);
- break;
- case 0x23:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: ncb_lana_num field invalid", ncbp->ncb_lsn, idx_session);
- break;
- case 0x24:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: command completed while cancel occurring", ncbp->ncb_lsn, idx_session);
- break;
- case 0x26:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: command not valid to cancel", ncbp->ncb_lsn, idx_session);
- break;
- case 0x30:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: name defined by anther local process", ncbp->ncb_lsn, idx_session);
- break;
- case 0x34:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: environment undefined. RESET required", ncbp->ncb_lsn, idx_session);
- break;
- case 0x35:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: required OS resources exhausted", ncbp->ncb_lsn, idx_session);
- break;
- case 0x36:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: max number of applications exceeded", ncbp->ncb_lsn, idx_session);
- break;
- case 0x37:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: no saps available for netbios", ncbp->ncb_lsn, idx_session);
- break;
- case 0x38:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: requested resources are not available", ncbp->ncb_lsn, idx_session);
- break;
- case 0x39:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: invalid ncb address or length > segment", ncbp->ncb_lsn, idx_session);
- break;
- case 0x3B:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: invalid NCB DDID", ncbp->ncb_lsn, idx_session);
- break;
- case 0x3C:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: lock of user area failed", ncbp->ncb_lsn, idx_session);
- break;
- case 0x3f:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: NETBIOS not loaded", ncbp->ncb_lsn, idx_session);
- break;
- case 0x40:
- osi_Log2(smb_logp, "NCBRECV failure lsn %d session %d: system error", ncbp->ncb_lsn, idx_session);
- break;
- default:
- osi_Log3(smb_logp, "NCBRECV failure lsn %d session %d code %d", ncbp->ncb_lsn, idx_session, rc);
- break;
- }
- }
+ if (rc != NRC_PENDING && rc != NRC_GOODRET)
+ osi_Log3(smb_logp, "NCBRECV failure lsn %d session %d: %s", ncbp->ncb_lsn, idx_session, ncb_error_string(rc));
switch (rc) {
case NRC_GOODRET:
+ vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
break;
case NRC_PENDING:
osi_Log2(smb_logp, "NCBRECV pending lsn %d session %d", ncbp->ncb_lsn, idx_session);
continue;
- case NRC_SCLOSED:
case NRC_SNUMOUT:
case NRC_SABORT:
+#ifndef DJGPP
+ LogEvent(EVENTLOG_WARNING_TYPE, MSG_UNEXPECTED_SMB_SESSION_CLOSE, ncb_error_string(rc));
+ /* fallthrough */
+#endif /* !DJGPP */
+ case NRC_SCLOSED:
/* Client closed session */
- dead_sessions[idx_session] = TRUE;
- if (vcp)
- smb_ReleaseVC(vcp);
vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
- /* Should also release vcp. [done] 2004-05-11 jaltman
- * Also, should do
- * sanity check that all TID's are gone.
- *
- * TODO: check if we could use LSNs[idx_session] instead,
- * also cleanup after dead vcp
- */
if (vcp) {
- if (dead_vcp == vcp)
- osi_Log1(smb_logp, "dead_vcp already set, 0x%x", dead_vcp);
- else if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
- osi_Log2(smb_logp, "setting dead_vcp 0x%x, user struct 0x%x",
+ lock_ObtainMutex(&vcp->mx);
+ if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+ osi_Log2(smb_logp, "marking dead vcp 0x%x, user struct 0x%x",
vcp, vcp->usersp);
- smb_HoldVC(vcp);
- if (dead_vcp) {
- smb_ReleaseVC(dead_vcp);
- osi_Log1(smb_logp,
- "Previous dead_vcp %x", dead_vcp);
- }
- dead_vcp = vcp;
vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
- }
-
- smb_CleanupDeadVC(vcp);
-
- if (vcp->justLoggedOut) {
- loggedOut = 1;
- loggedOutTime = vcp->logoffTime;
- loggedOutName = strdup(vcp->justLoggedOut->unp->name);
- loggedOutUserp = vcp->justLoggedOut;
- lock_ObtainWrite(&smb_rctLock);
- loggedOutUserp->refCount++;
- lock_ReleaseWrite(&smb_rctLock);
- }
+ 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;
case NRC_INCOMP:
/* Treat as transient error */
- {
#ifndef DJGPP
- LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_INCOMPLETE,
- ncbp->ncb_length);
+ LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_INCOMPLETE,
+ ncbp->ncb_length);
#endif /* !DJGPP */
- osi_Log1(smb_logp,
- "dispatch smb recv failed, message incomplete, ncb_length %d",
- ncbp->ncb_length);
- osi_Log1(smb_logp,
- "SMB message incomplete, "
- "length %d", ncbp->ncb_length);
-
- /*
- * We used to discard the packet.
- * Instead, try handling it normally.
- *
- continue;
- */
- break;
- }
+ osi_Log1(smb_logp,
+ "dispatch smb recv failed, message incomplete, ncb_length %d",
+ ncbp->ncb_length);
+ osi_Log1(smb_logp,
+ "SMB message incomplete, "
+ "length %d", ncbp->ncb_length);
+
+ /*
+ * We used to discard the packet.
+ * Instead, try handling it normally.
+ *
+ continue;
+ */
+ vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
+ break;
default:
- /* A weird error code. Log it, sleep, and
- * continue. */
+ /* A weird error code. Log it, sleep, and continue. */
+ vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
+ 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);
- dead_sessions[idx_session] = TRUE;
+ 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)
+ lock_ReleaseMutex(&vcp->mx);
thrd_Sleep(1000);
- thrd_SetEvent(SessionEvents[idx_session]);
+ thrd_SetEvent(SessionEvents[idx_session]);
}
- continue;
+ continue;
}
/* Success, so now dispatch on all the data in the packet */
if (smb_concurrentCalls > smb_maxObsConcurrentCalls)
smb_maxObsConcurrentCalls = smb_concurrentCalls;
- if (vcp)
- smb_ReleaseVC(vcp);
- vcp = smb_FindVC(ncbp->ncb_lsn, 0, ncbp->ncb_lana_num);
/*
* If at this point vcp is NULL (implies that packet was invalid)
* then we are in big trouble. This means either :
continue;
}
-
vcp->errorCount = 0;
bufp = (struct smb_packet *) ncbp->ncb_buffer;
#ifdef DJGPP
NCB *ncbp;
long code = 0;
long len;
- long i, j;
- smb_vc_t *vcp = 0;
+ long i;
+ int session, thread;
+ smb_vc_t *vcp = NULL;
int flags = 0;
char rname[NCBNAMSZ+1];
char cname[MAX_COMPUTERNAME_LENGTH+1];
if (strncmp(rname, cname, NCBNAMSZ) != 0)
flags |= SMB_VCFLAG_REMOTECONN;
- osi_Log1(smb_logp, "New session lsn %d", ncbp->ncb_lsn);
/* lock */
lock_ObtainMutex(&smb_ListenerLock);
- /* New generation */
- sessionGen++;
+ osi_Log1(smb_logp, "NCBLISTEN completed, call from %s", osi_LogSaveString(smb_logp, rname));
+ osi_Log1(smb_logp, "SMB session startup, %d ongoing ops", ongoingOps);
+
+ /* now ncbp->ncb_lsn is the connection ID */
+ vcp = smb_FindVC(ncbp->ncb_lsn, SMB_FLAG_CREATE, ncbp->ncb_lana_num);
+ if (vcp->session == 0) {
+ /* New generation */
+ osi_Log1(smb_logp, "New session lsn %d", ncbp->ncb_lsn);
+ sessionGen++;
- /* Log session startup */
+ /* Log session startup */
#ifdef NOTSERVICE
- fprintf(stderr, "New session(ncb_lsn,ncb_lana_num) %d,%d starting from host "
- "%s\n",
- ncbp->ncb_lsn,ncbp->ncb_lana_num, rname);
+ fprintf(stderr, "New session(ncb_lsn,ncb_lana_num) %d,%d starting from host %s\n",
+ ncbp->ncb_lsn,ncbp->ncb_lana_num, rname);
#endif /* NOTSERVICE */
- osi_Log4(smb_logp, "New session(ncb_lsn,ncb_lana_num) (%d,%d) starting from host %s, %d ongoing ops",
- ncbp->ncb_lsn,ncbp->ncb_lana_num, osi_LogSaveString(smb_logp, rname), ongoingOps);
+ osi_Log4(smb_logp, "New session(ncb_lsn,ncb_lana_num) (%d,%d) starting from host %s, %d ongoing ops",
+ ncbp->ncb_lsn,ncbp->ncb_lana_num, osi_LogSaveString(smb_logp, rname), ongoingOps);
- if (reportSessionStartups) {
+ if (reportSessionStartups) {
#ifndef DJGPP
- LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SMB_SESSION_START, ongoingOps);
+ LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SMB_SESSION_START, ongoingOps);
#else /* DJGPP */
- time(&now);
- fprintf(stderr, "%s: New session %d starting from host %s\n",
- asctime(localtime(&now)), ncbp->ncb_lsn, rname);
- fflush(stderr);
+ time(&now);
+ fprintf(stderr, "%s: New session %d starting from host %s\n",
+ asctime(localtime(&now)), ncbp->ncb_lsn, rname);
+ fflush(stderr);
#endif /* !DJGPP */
- }
- osi_Log1(smb_logp, "NCBLISTEN completed, call from %s", osi_LogSaveString(smb_logp, rname));
- osi_Log1(smb_logp, "SMB session startup, %d ongoing ops",
- ongoingOps);
+ }
+
+ lock_ObtainMutex(&vcp->mx);
+ strcpy(vcp->rname, rname);
+ vcp->flags |= flags;
+ lock_ReleaseMutex(&vcp->mx);
+
+ /* Allocate slot in session arrays */
+ /* Re-use dead session if possible, otherwise add one more */
+ /* But don't look at session[0], it is reserved */
+ lock_ObtainWrite(&smb_globalLock);
+ for (session = 1; session < numSessions; session++) {
+ if (dead_sessions[session]) {
+ osi_Log1(smb_logp, "connecting to dead session [ %d ]", session);
+ dead_sessions[session] = FALSE;
+ break;
+ }
+ }
+ lock_ReleaseWrite(&smb_globalLock);
+ } else {
+ /* We are re-using an existing VC because the lsn and lana
+ * were re-used */
+ session = vcp->session;
+
+ osi_Log1(smb_logp, "Re-using session lsn %d", ncbp->ncb_lsn);
+
+ /* Log session startup */
+#ifdef NOTSERVICE
+ fprintf(stderr, "Re-using session(ncb_lsn,ncb_lana_num) %d,%d starting from host %s\n",
+ ncbp->ncb_lsn,ncbp->ncb_lana_num, rname);
+#endif /* NOTSERVICE */
+ osi_Log4(smb_logp, "Re-using session(ncb_lsn,ncb_lana_num) (%d,%d) starting from host %s, %d ongoing ops",
+ ncbp->ncb_lsn,ncbp->ncb_lana_num, osi_LogSaveString(smb_logp, rname), ongoingOps);
- /* now ncbp->ncb_lsn is the connection ID */
- vcp = smb_FindVC(ncbp->ncb_lsn, SMB_FLAG_CREATE, ncbp->ncb_lana_num);
- vcp->flags |= flags;
- strcpy(vcp->rname, rname);
-
- /* Allocate slot in session arrays */
- /* Re-use dead session if possible, otherwise add one more */
- /* But don't look at session[0], it is reserved */
- for (i = 1; i < numSessions; i++) {
- if (dead_sessions[i]) {
- osi_Log1(smb_logp, "connecting to dead session [ %d ]", i);
- dead_sessions[i] = FALSE;
- break;
- }
- }
+ if (reportSessionStartups) {
+#ifndef DJGPP
+ LogEvent(EVENTLOG_INFORMATION_TYPE, MSG_SMB_SESSION_START, ongoingOps);
+#else /* DJGPP */
+ time(&now);
+ fprintf(stderr, "%s: Re-using session %d starting from host %s\n",
+ asctime(localtime(&now)), ncbp->ncb_lsn, rname);
+ fflush(stderr);
+#endif /* !DJGPP */
+ }
+ }
- if (i >= Sessionmax - 1 || numNCBs >= NCBmax - 1) {
+ if (session >= SESSION_MAX - 1 || numNCBs >= NCB_MAX - 1) {
unsigned long code = CM_ERROR_ALLBUSY;
smb_packet_t * outp = GetPacket();
unsigned char *outWctp;
smb_t *smbp;
+ smb_FormatResponsePacket(vcp, NULL, outp);
outp->ncbp = ncbp;
if (vcp->flags & SMB_VCFLAG_STATUS32) {
}
smb_SendPacket(vcp, outp);
smb_FreePacket(outp);
+
+ lock_ObtainMutex(&vcp->mx);
+ vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+ lock_ReleaseMutex(&vcp->mx);
+ smb_CleanupDeadVC(vcp);
} else {
/* assert that we do not exceed the maximum number of sessions or NCBs.
- * we should probably want to wait for a session to be freed in case
- * we run out.
- */
- osi_assert(i < Sessionmax - 1);
- osi_assert(numNCBs < NCBmax - 1); /* if we pass this test we can allocate one more */
-
- LSNs[i] = ncbp->ncb_lsn;
- lanas[i] = ncbp->ncb_lana_num;
+ * we should probably want to wait for a session to be freed in case
+ * we run out.
+ */
+ osi_assert(session < SESSION_MAX - 1);
+ osi_assert(numNCBs < NCB_MAX - 1); /* if we pass this test we can allocate one more */
+
+ lock_ObtainMutex(&vcp->mx);
+ vcp->session = session;
+ lock_ReleaseMutex(&vcp->mx);
+ lock_ObtainWrite(&smb_globalLock);
+ LSNs[session] = ncbp->ncb_lsn;
+ lanas[session] = ncbp->ncb_lana_num;
+ lock_ReleaseWrite(&smb_globalLock);
- if (i == numSessions) {
+ if (session == numSessions) {
/* Add new NCB for new session */
char eventName[MAX_PATH];
osi_Log1(smb_logp, "smb_Listener creating new session %d", i);
InitNCBslot(numNCBs);
+ lock_ObtainWrite(&smb_globalLock);
numNCBs++;
+ lock_ReleaseWrite(&smb_globalLock);
thrd_SetEvent(NCBavails[0]);
thrd_SetEvent(NCBevents[0]);
- for (j = 0; j < smb_NumServerThreads; j++)
- thrd_SetEvent(NCBreturns[j][0]);
+ for (thread = 0; thread < smb_NumServerThreads; thread++)
+ thrd_SetEvent(NCBreturns[thread][0]);
/* Also add new session event */
- sprintf(eventName, "SessionEvents[%d]", i);
- SessionEvents[i] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName);
+ sprintf(eventName, "SessionEvents[%d]", session);
+ SessionEvents[session] = thrd_CreateEvent(NULL, FALSE, TRUE, eventName);
if ( GetLastError() == ERROR_ALREADY_EXISTS )
osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
+ lock_ObtainWrite(&smb_globalLock);
numSessions++;
+ lock_ReleaseWrite(&smb_globalLock);
osi_Log2(smb_logp, "increasing numNCBs [ %d ] numSessions [ %d ]", numNCBs, numSessions);
thrd_SetEvent(SessionEvents[0]);
} else {
- thrd_SetEvent(SessionEvents[i]);
+ thrd_SetEvent(SessionEvents[session]);
}
}
-
smb_ReleaseVC(vcp);
/* unlock */
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: %s", eventName);
for (i = 0; i < smb_NumServerThreads; i++) {
- NCBreturns[i] = malloc(NCBmax * sizeof(EVENT_HANDLE));
+ NCBreturns[i] = malloc(NCB_MAX * sizeof(EVENT_HANDLE));
NCBreturns[i][0] = retHandle;
}
*cp = 0;
- osi_Log0( smb_logp, osi_LogSaveString(smb_logp, buf));
+ osi_Log1( smb_logp, "%s", osi_LogSaveString(smb_logp, buf));
}
osi_Log0(smb_logp, "*** End SMB packet dump ***");
sprintf(output, "done dumping smb_vc_t\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+ sprintf(output, "begin dumping DEAD smb_vc_t\n");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+ 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\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\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\n",
+ cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->ioctlp,
+ fidp->NTopen_pathp ? fidp->NTopen_pathp : "NULL",
+ fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : "NULL");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+ }
+
+ sprintf(output, "done dumping smb_fid_t\n");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+ }
+
+ sprintf(output, "done dumping DEAD smb_vc_t\n");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+ sprintf(output, "begin dumping DEAD smb_vc_t\n");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
+ 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\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\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\n",
+ cookie, fidp, fidp->refCount, fidp->fid, fidp->vcp, fidp->scp, fidp->ioctlp,
+ fidp->NTopen_pathp ? fidp->NTopen_pathp : "NULL",
+ fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : "NULL");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+ }
+
+ sprintf(output, "done dumping smb_fid_t\n");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+ }
+
+ sprintf(output, "done dumping DEAD smb_vc_t\n");
+ WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
+
if (lock)
lock_ReleaseRead(&smb_rctLock);
return 0;