/* These characters are illegal in Windows filenames */
static char *illegalChars = "\\/:*?\"<>|";
-int smbShutdownFlag = 0;
+static int smbShutdownFlag = 0;
+static int smb_ListenerState = SMB_LISTENER_UNINITIALIZED;
int smb_LogoffTokenTransfer;
time_t smb_LogoffTransferTimeout;
extern void afsi_log(char *pattern, ...);
extern HANDLE afsi_file;
+extern int powerStateSuspended;
osi_hyper_t hzero = {0, 0};
osi_hyper_t hones = {0xFFFFFFFF, -1};
char smb_LANadapter;
unsigned char smb_sharename[NCBNAMSZ+1] = {0};
+BOOL isGateway = FALSE;
+
/* for debugging */
long smb_maxObsConcurrentCalls=0;
long smb_concurrentCalls=0;
/* forward decl */
void smb_DispatchPacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp,
NCB *ncbp, raw_write_cont_t *rwcp);
-void smb_NetbiosInit();
+int smb_NetbiosInit(void);
#ifdef LOG_PACKET
void smb_LogPacket(smb_packet_t *packet);
fidp->refCount++;
}
+
+/* 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 */
void smb_ReleaseFID(smb_fid_t *fidp)
{
cm_scache_t *scp = NULL;
vcp = fidp->vcp;
fidp->vcp = NULL;
scp = fidp->scp; /* release after lock is released */
- fidp->scp = NULL;
+ if (scp) {
+ lock_ObtainMutex(&scp->mx);
+ scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
+ lock_ReleaseMutex(&scp->mx);
+ osi_Log2(smb_logp,"smb_ReleaseFID fidp 0x%p scp 0x%p", fidp, scp);
+ fidp->scp = NULL;
+ }
userp = fidp->userp;
fidp->userp = NULL;
return 0;
}
+ /* Check for volume references
+ *
+ * They look like <cell>{%,#}<volume>
+ */
+ if (strchr(shareName, '%') != NULL ||
+ strchr(shareName, '#') != NULL) {
+ char pathstr[CELL_MAXNAMELEN + VL_MAXNAMELEN + 1 + CM_PREFIX_VOL_CCH];
+ /* make room for '/@vol:' + mountchar + NULL terminator*/
+
+ osi_Log1(smb_logp, "smb_FindShare found volume reference [%s]",
+ osi_LogSaveString(smb_logp, shareName));
+
+ snprintf(pathstr, sizeof(pathstr)/sizeof(char),
+ "/" CM_PREFIX_VOL "%s", shareName);
+ pathstr[sizeof(pathstr)/sizeof(char) - 1] = '\0';
+ len = strlen(pathstr) + 1;
+
+ *pathNamep = malloc(len);
+ if (*pathNamep) {
+ strcpy(*pathNamep, pathstr);
+ strlwr(*pathNamep);
+ osi_Log1(smb_logp, " returning pathname [%s]",
+ osi_LogSaveString(smb_logp, *pathNamep));
+
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
0, KEY_QUERY_VALUE, &parmKey);
if (code == ERROR_SUCCESS) {
{
lock_ObtainWrite(&smb_globalLock);
lock_ObtainMutex(&dsp->mx);
+ osi_Log3(smb_logp,"smb_DeleteDirSearch cookie %d dsp 0x%p scp 0x%p",
+ dsp->cookie, dsp, dsp->scp);
dsp->flags |= SMB_DIRSEARCH_DELETE;
if (dsp->scp != NULL) {
lock_ObtainMutex(&dsp->scp->mx);
lock_ReleaseMutex(&dsp->mx);
lock_FinalizeMutex(&dsp->mx);
scp = dsp->scp;
+ osi_Log3(smb_logp,"smb_ReleaseDirSearch cookie %d dsp 0x%p scp 0x%p",
+ dsp->cookie, dsp, scp);
free(dsp);
} else {
lock_ReleaseMutex(&dsp->mx);
counter = 0;
/* what's the biggest ID allowed in this version of the protocol */
+ /* TODO: do we really want a non v3 dir search request to wrap
+ smb_dirSearchCounter? */
maxAllowed = isV3 ? 65535 : 255;
if (smb_dirSearchCounter > maxAllowed)
smb_dirSearchCounter = 1;
osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q);
if (!smb_lastDirSearchp)
smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q;
- break;
+
+ osi_Log2(smb_logp,"smb_NewDirSearch cookie %d dsp 0x%p",
+ dsp->cookie, dsp);
+ break;
}
lock_ReleaseWrite(&smb_globalLock);
return dsp;
}
/* return the parm'th parameter in the smbp packet */
-unsigned int smb_GetSMBParm(smb_packet_t *smbp, int parm)
+unsigned short smb_GetSMBParm(smb_packet_t *smbp, int parm)
{
int parmCount;
unsigned char *parmDatap;
}
/* return the parm'th parameter in the smbp packet */
+unsigned char smb_GetSMBParmByte(smb_packet_t *smbp, int parm)
+{
+ int parmCount;
+ unsigned char *parmDatap;
+
+ parmCount = *smbp->wctp;
+
+ if (parm >= parmCount) {
+ char s[100];
+
+ sprintf(s, "Bad SMB param %d out of %d, ncb len %d",
+ parm, parmCount, smbp->ncb_length);
+ osi_Log3(smb_logp,"Bad SMB param %d out of %d, ncb len %d",
+ parm, parmCount, smbp->ncb_length);
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM,
+ __FILE__, __LINE__, parm, parmCount, smbp->ncb_length);
+ osi_panic(s, __FILE__, __LINE__);
+ }
+ parmDatap = smbp->wctp + (2*parm) + 1;
+
+ return parmDatap[0];
+}
+
+/* return the parm'th parameter in the smbp packet */
unsigned int smb_GetSMBParmLong(smb_packet_t *smbp, int parm)
{
int parmCount;
#endif
else if (code == RXKADUNKNOWNKEY) {
NTStatus = 0xC0000322L; /* Bad Kerberos key */
+ }
+ else if (code == CM_ERROR_BAD_LEVEL) {
+ NTStatus = 0xC0000148L; /* Invalid Level */
} else {
NTStatus = 0xC0982001L; /* SMB non-specific error */
}
wlRequest);
scp = wlRequest->scp;
+ osi_Log2(smb_logp,"smb_WaitingLocksDaemon wlRequest 0x%p scp 0x%p", wlRequest, scp);
cm_InitReq(&req);
lock_ObtainMutex(&dsp->mx);
if (dsp->scp) {
scp = dsp->scp;
+ osi_Log2(smb_logp,"smb_ReceiveCoreSearchDir (1) dsp 0x%p scp 0x%p", dsp, scp);
cm_HoldSCache(scp);
code = 0;
} else {
#endif /* DFS_SUPPORT */
dsp->scp = scp;
+ osi_Log2(smb_logp,"smb_ReceiveCoreSearchDir (2) dsp 0x%p scp 0x%p", dsp, scp);
/* we need one hold for the entry we just stored into,
* and one for our own processing. When we're done with this
* function, we'll drop the one for our own processing.
"has filetype %d", osi_LogSaveString(smb_logp, dep->name),
fileType);
if (fileType == CM_SCACHETYPE_DIRECTORY ||
+ fileType == CM_SCACHETYPE_MOUNTPOINT ||
fileType == CM_SCACHETYPE_DFSLINK ||
fileType == CM_SCACHETYPE_INVALID)
osi_Log0(smb_logp, "SMB search dir skipping directory or bad link");
/* save a pointer to the vnode */
fidp->scp = scp;
+ osi_Log2(smb_logp,"smb_ReceiveCoreOpen fidp 0x%p scp 0x%p", fidp, scp);
+ lock_ObtainMutex(&scp->mx);
+ scp->flags |= CM_SCACHEFLAG_SMB_FID;
+ lock_ReleaseMutex(&scp->mx);
+
/* and the user */
cm_HoldUser(userp);
fidp->userp = userp;
lock_ObtainMutex(&fidp->mx);
if ((share & 0xf) == 0)
- fidp->flags |= SMB_FID_OPENREAD;
+ fidp->flags |= SMB_FID_OPENREAD_LISTDIR;
else if ((share & 0xf) == 1)
fidp->flags |= SMB_FID_OPENWRITE;
else
- fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
+ fidp->flags |= (SMB_FID_OPENREAD_LISTDIR | SMB_FID_OPENWRITE);
lock_ReleaseMutex(&fidp->mx);
lock_ObtainMutex(&scp->mx);
char *maskp; /* pointer to star pattern of old file name */
int flags; /* tilde, casefold, etc */
char *newNamep; /* ptr to the new file's name */
+ int any;
} smb_renameRock_t;
int smb_RenameProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
smb_renameRock_t *rockp;
int caseFold;
int match;
- char shortName[13];
+ char shortName[13]="";
rockp = (smb_renameRock_t *) vrockp;
match = smb_V3MatchMask(shortName, rockp->maskp, caseFold);
}
if (match) {
- code = cm_Rename(rockp->odscp, dep->name,
+ rockp->any = 1;
+
+ code = cm_Rename(rockp->odscp, dep->name,
rockp->ndscp, rockp->newNamep, rockp->userp,
rockp->reqp);
/* if the call worked, stop doing the search now, since we
* really only want to rename one file.
*/
+ osi_Log1(smb_logp, "cm_Rename returns %ld", code);
if (code == 0)
code = CM_ERROR_STOPNOW;
}
- else code = 0;
+ else
+ code = 0;
return code;
}
rock.maskp = oldLastNamep;
rock.flags = ((strchr(oldLastNamep, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0);
rock.newNamep = newLastNamep;
+ rock.any = 0;
/* Check if the file already exists; if so return error */
code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp);
if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) {
osi_Log2(smb_logp, " lookup returns %ld for [%s]", code,
- osi_LogSaveString(afsd_logp, newLastNamep));
+ osi_LogSaveString(smb_logp, newLastNamep));
/* Check if the old and the new names differ only in case. If so return
* success, else return CM_ERROR_EXISTS
thyper.HighPart = 0;
code = cm_ApplyDir(oldDscp, smb_RenameProc, &rock, &thyper, userp, &req, NULL);
+ if (code == 0 && !rock.any) {
+ thyper.LowPart = 0;
+ thyper.HighPart = 0;
+ rock.flags |= SMB_MASKFLAG_CASEFOLD;
+ code = cm_ApplyDir(oldDscp, smb_RenameProc, &rock, &thyper, userp, &req, NULL);
+ }
osi_Log1(smb_logp, "smb_RenameProc returns %ld", code);
if (code == CM_ERROR_STOPNOW)
code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp);
if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) {
osi_Log2(smb_logp, " lookup returns %ld for [%s]", code,
- osi_LogSaveString(afsd_logp, newLastNamep));
+ osi_LogSaveString(smb_logp, newLastNamep));
/* if the existing link is to the same file, then we return success */
if (!code) {
char *oldPathp;
char *newPathp;
char *tp;
+ long code;
tp = smb_GetSMBData(inp, NULL);
oldPathp = smb_ParseASCIIBlock(tp, &tp);
OemToChar(newPathp,newPathp);
osi_Log2(smb_logp, "smb rename [%s] to [%s]",
- osi_LogSaveString(smb_logp, oldPathp),
- osi_LogSaveString(smb_logp, newPathp));
+ osi_LogSaveString(smb_logp, oldPathp),
+ osi_LogSaveString(smb_logp, newPathp));
+
+ code = smb_Rename(vcp,inp,oldPathp,newPathp,0);
- return smb_Rename(vcp,inp,oldPathp,newPathp,0);
+ osi_Log1(smb_logp, "smb rename returns 0x%x", code);
+ return code;
}
rock.userp = userp;
rock.reqp = &req;
rock.dscp = dscp;
+
/* First do a case sensitive match, and if that fails, do a case insensitive match */
code = cm_ApplyDir(dscp, smb_RmdirProc, &rock, &thyper, userp, &req, NULL);
if (code == 0 && !rock.any) {
afs_uint32 dosTime) {
long code = 0;
cm_req_t req;
- cm_scache_t *dscp = fidp->NTopen_dscp;
- char *pathp = fidp->NTopen_pathp;
- cm_scache_t * scp = fidp->scp;
+ cm_scache_t *dscp = NULL;
+ char *pathp = NULL;
+ cm_scache_t * scp = NULL;
int deleted = 0;
int nullcreator = 0;
- osi_Log3(smb_logp, "smb_CloseFID Closing fidp 0x%x (fid=%d vcp=0x%x)",
- fidp, fidp->fid, vcp);
+ osi_Log4(smb_logp, "smb_CloseFID Closing fidp 0x%x (fid=%d scp=0x%x vcp=0x%x)",
+ fidp, fidp->fid, scp, vcp);
if (!userp) {
lock_ObtainMutex(&fidp->mx);
lock_ReleaseWrite(&smb_rctLock);
lock_ObtainMutex(&fidp->mx);
+ if (fidp->NTopen_dscp) {
+ dscp = fidp->NTopen_dscp;
+ cm_HoldSCache(dscp);
+ }
+
+ if (fidp->NTopen_pathp) {
+ pathp = strdup(fidp->NTopen_pathp);
+ }
+
+ if (fidp->scp) {
+ scp = fidp->scp;
+ cm_HoldSCache(scp);
+ }
+
/* Don't jump the gun on an async raw write */
while (fidp->raw_writers) {
lock_ReleaseMutex(&fidp->mx);
}
if (fidp->flags & SMB_FID_NTOPEN) {
+ cm_ReleaseSCache(fidp->NTopen_dscp);
fidp->NTopen_dscp = NULL;
+ free(fidp->NTopen_pathp);
fidp->NTopen_pathp = NULL;
fidp->flags &= ~SMB_FID_NTOPEN;
+ } else {
+ osi_assert(fidp->NTopen_dscp == NULL);
+ osi_assert(fidp->NTopen_pathp == NULL);
}
+
if (fidp->NTopen_wholepathp) {
- free(fidp->NTopen_wholepathp);
- fidp->NTopen_wholepathp = NULL;
+ free(fidp->NTopen_wholepathp);
+ fidp->NTopen_wholepathp = NULL;
+ }
+
+ if (fidp->scp) {
+ cm_ReleaseSCache(fidp->scp);
+ fidp->scp = NULL;
}
- fidp->scp = NULL;
lock_ReleaseMutex(&fidp->mx);
if (dscp)
scp->flags |= CM_SCACHEFLAG_DELETED;
lock_ReleaseMutex(&scp->mx);
}
+ lock_ObtainMutex(&scp->mx);
+ scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
+ lock_ReleaseMutex(&scp->mx);
cm_ReleaseSCache(scp);
}
lock_ObtainMutex(&fidp->mx);
scp = fidp->scp;
+ cm_HoldSCache(scp);
lock_ObtainMutex(&scp->mx);
if (offset.HighPart == 0) {
if (code == 0 && sequential)
cm_ConsiderPrefetch(scp, &lastByte, userp, &req);
+ cm_ReleaseSCache(scp);
+
return code;
}
offset = LargeIntegerAdd(offset,
ConvertLongToLargeInteger(written));
- count -= written;
+ count -= (unsigned short)written;
total_written += written;
written = 0;
}
lock_ObtainMutex(&fidp->mx);
/* always create it open for read/write */
- fidp->flags |= (SMB_FID_OPENREAD | SMB_FID_OPENWRITE);
+ fidp->flags |= (SMB_FID_OPENREAD_LISTDIR | SMB_FID_OPENWRITE);
/* remember that the file was newly created */
if (created)
fidp->flags |= SMB_FID_CREATED;
+ osi_Log2(smb_logp,"smb_ReceiveCoreCreate fidp 0x%p scp 0x%p", fidp, scp);
+
/* save a pointer to the vnode */
fidp->scp = scp;
+ lock_ObtainMutex(&scp->mx);
+ scp->flags |= CM_SCACHEFLAG_SMB_FID;
+ lock_ReleaseMutex(&scp->mx);
+
/* and the user */
fidp->userp = userp;
lock_ReleaseMutex(&fidp->mx);
GetComputerName(cname, &cnamelen);
_strupr(cname);
- while (1) {
+ while (smb_ListenerState == SMB_LISTENER_STARTED) {
memset(ncbp, 0, sizeof(NCB));
flags = 0;
code = Netbios(ncbp);
- if (code != 0)
- {
+ if (code == NRC_BRIDGE) {
+ int lanaRemaining = 0;
+
+ if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) {
+ ExitThread(1);
+ }
+
+ osi_Log2(smb_logp,
+ "NCBLISTEN lana=%d failed with NRC_BRIDGE. Listener thread exiting.",
+ ncbp->ncb_lana_num, code);
+
+ for (i = 0; i < lana_list.length; i++) {
+ if (lana_list.lana[i] == ncbp->ncb_lana_num) {
+ smb_StopListener(ncbp, lana_list.lana[i]);
+ lana_list.lana[i] = 255;
+ }
+ if (lana_list.lana[i] != 255)
+ lanaRemaining++;
+ }
+
+ if (lanaRemaining == 0) {
+ cm_VolStatus_Network_Stopped(cm_NetbiosName
+#ifdef _WIN64
+ ,cm_NetbiosName
+#endif
+ );
+ smb_ListenerState = SMB_LISTENER_STOPPED;
+ smb_LANadapter = -1;
+ lana_list.length = 0;
+ }
+ FreeNCB(ncbp);
+ return;
+ } else if (code != 0) {
char tbuffer[256];
/* terminate silently if shutdown flag is set */
- if (smbShutdownFlag == 1) {
+ if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) {
ExitThread(1);
}
/* unlock */
lock_ReleaseMutex(&smb_ListenerLock);
} /* dispatch while loop */
+
+ FreeNCB(ncbp);
}
/* initialize Netbios */
-void smb_NetbiosInit()
+int smb_NetbiosInit(void)
{
NCB *ncbp;
int i, lana, code, l;
int delname_tried=0;
int len;
int lana_found = 0;
- OSVERSIONINFO Version;
-
- /* Get the version of Windows */
- memset(&Version, 0x00, sizeof(Version));
- Version.dwOSVersionInfoSize = sizeof(Version);
- GetVersionEx(&Version);
+ lana_number_t lanaNum;
/* setup the NCB system */
ncbp = 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))) {
+ smb_LANadapter = (lanaNum == LANA_INVALID)? -1: lanaNum;
+
+ if (smb_LANadapter != -1)
+ afsi_log("LAN adapter number %d", smb_LANadapter);
+ else
+ afsi_log("LAN adapter number not determined");
+
+ if (isGateway)
+ afsi_log("Set for gateway service");
+
+ afsi_log("Using >%s< as SMB server name", cm_NetbiosName);
+ } else {
+ /* something went horribly wrong. We can't proceed without a netbios name */
+ char buf[128];
+ StringCbPrintfA(buf,sizeof(buf),"Netbios name could not be determined: %li", code);
+ osi_panic(buf, __FILE__, __LINE__);
+ }
+
+ /* remember the name */
+ len = (int)strlen(cm_NetbiosName);
+ if (smb_localNamep)
+ free(smb_localNamep);
+ smb_localNamep = malloc(len+1);
+ strcpy(smb_localNamep, cm_NetbiosName);
+ afsi_log("smb_localNamep is >%s<", smb_localNamep);
+
+
if (smb_LANadapter == -1) {
ncbp->ncb_command = NCBENUM;
ncbp->ncb_buffer = (PUCHAR)&lana_list;
afsi_log("Netbios NCBADDNAME added new name >%s<",name);
}
- if (code == 0) code = ncbp->ncb_retcode;
+ if (code == 0)
+ code = ncbp->ncb_retcode;
+
if (code == 0) {
afsi_log("Netbios NCBADDNAME succeeded on lana %d\n", lana);
}
else {
afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
lana_list.lana[l] = 255; /* invalid lana */
- osi_panic(s, __FILE__, __LINE__);
}
}
if (code == 0) {
osi_assert(lana_list.length >= 0);
if (!lana_found) {
- osi_panic("No valid LANA numbers found!", __FILE__, __LINE__);
+ afsi_log("No valid LANA numbers found!");
+ lana_list.length = 0;
+ smb_LANadapter = -1;
+ smb_ListenerState = SMB_LISTENER_STOPPED;
+ cm_VolStatus_Network_Stopped(cm_NetbiosName
+#ifdef _WIN64
+ ,cm_NetbiosName
+#endif
+ );
}
/* we're done with the NCB now */
FreeNCB(ncbp);
+
+ return (lana_list.length > 0 ? 1 : 0);
+}
+
+void smb_StartListeners()
+{
+ int i;
+ int lpid;
+ thread_t phandle;
+
+ if (smb_ListenerState == SMB_LISTENER_STARTED)
+ return;
+
+ smb_ListenerState = SMB_LISTENER_STARTED;
+ cm_VolStatus_Network_Started(cm_NetbiosName
+#ifdef _WIN64
+ , cm_NetbiosName
+#endif
+ );
+
+ for (i = 0; i < lana_list.length; i++) {
+ if (lana_list.lana[i] == 255)
+ continue;
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_Listener,
+ (void*)lana_list.lana[i], 0, &lpid, "smb_Listener");
+ osi_assert(phandle != NULL);
+ thrd_CloseHandle(phandle);
+ }
+}
+
+void smb_RestartListeners()
+{
+ if (!powerStateSuspended && smb_ListenerState == SMB_LISTENER_STOPPED) {
+ if (smb_NetbiosInit())
+ smb_StartListeners();
+ }
+}
+
+void smb_StopListener(NCB *ncbp, int lana)
+{
+ long code;
+
+ memset(ncbp, 0, sizeof(*ncbp));
+ ncbp->ncb_command = NCBDELNAME;
+ ncbp->ncb_lana_num = lana;
+ memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
+ code = Netbios(ncbp);
+
+ afsi_log("Netbios NCBDELNAME lana=%d code=%d retcode=%d complete=%d",
+ lana, code, ncbp->ncb_retcode, ncbp->ncb_cmd_cplt);
+
+ /* and then reset the LANA; this will cause the listener threads to exit */
+ ncbp->ncb_command = NCBRESET;
+ ncbp->ncb_callname[0] = 100;
+ ncbp->ncb_callname[2] = 100;
+ ncbp->ncb_lana_num = lana;
+ code = Netbios(ncbp);
+ if (code == 0)
+ code = ncbp->ncb_retcode;
+ if (code != 0) {
+ afsi_log("Netbios NCBRESET lana %d error code %d", lana, code);
+ } else {
+ afsi_log("Netbios NCBRESET lana %d succeeded", lana);
+ }
}
-void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
+void smb_StopListeners(void)
+{
+ NCB *ncbp;
+ int lana, l;
+
+ if (smb_ListenerState == SMB_LISTENER_STOPPED)
+ return;
+
+ smb_ListenerState = SMB_LISTENER_STOPPED;
+ cm_VolStatus_Network_Stopped(cm_NetbiosName
+#ifdef _WIN64
+ , cm_NetbiosName
+#endif
+ );
+
+ ncbp = GetNCB();
+
+ /* Unregister the SMB name */
+ for (l = 0; l < lana_list.length; l++) {
+ lana = lana_list.lana[l];
+
+ if (lana != 255) {
+ smb_StopListener(ncbp, lana);
+
+ /* mark the adapter invalid */
+ lana_list.lana[l] = 255; /* invalid lana */
+ }
+ }
+
+ /* force a re-evaluation of the network adapters */
+ lana_list.length = 0;
+ smb_LANadapter = -1;
+ FreeNCB(ncbp);
+ Sleep(1000); /* give the listener threads a chance to exit */
+}
+
+void smb_Init(osi_log_t *logp, int useV3,
int nThreads
, void *aMBfunc
)
thread_t phandle;
int lpid;
INT_PTR i;
- int len;
struct tm myTime;
EVENT_HANDLE retHandle;
char eventName[MAX_PATH];
smb_MBfunc = aMBfunc;
smb_useV3 = useV3;
- smb_LANadapter = LANadapt;
/* Initialize smb_localZero */
myTime.tm_isdst = -1; /* compute whether on DST or not */
/* initialize the remote debugging log */
smb_logp = logp;
- /* remember the name */
- len = (int)strlen(snamep);
- smb_localNamep = malloc(len+1);
- strcpy(smb_localNamep, snamep);
- afsi_log("smb_localNamep is >%s<", smb_localNamep);
-
/* and the global lock */
lock_InitializeRWLock(&smb_globalLock, "smb global lock");
lock_InitializeRWLock(&smb_rctLock, "smb refct and tree struct lock");
* performance by removing the network access and works around a bug
* seen at sites which are using a MIT Kerberos principal to login
* to machines joined to a non-root domain in a multi-domain forest.
+ * MsV1_0SetProcessOption was added in Windows XP.
*/
PVOID pResponse = NULL;
ULONG cbResponse = 0;
/* Start listeners, waiters, servers, and daemons */
- for (i = 0; i < lana_list.length; i++) {
- if (lana_list.lana[i] == 255)
- continue;
- phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_Listener,
- (void*)lana_list.lana[i], 0, &lpid, "smb_Listener");
- osi_assert(phandle != NULL);
- thrd_CloseHandle(phandle);
- }
+ smb_StartListeners();
phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_ClientWaiter,
NULL, 0, &lpid, "smb_ClientWaiter");
if (fidp->scp != NULL) {
scp = fidp->scp;
fidp->scp = NULL;
+ lock_ObtainMutex(&scp->mx);
+ scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
+ lock_ReleaseMutex(&scp->mx);
+ osi_Log2(smb_logp,"smb_Shutdown fidp 0x%p scp 0x%p", fidp, scp);
cm_ReleaseSCache(scp);
}
lock_ReleaseMutex(&fidp->mx);
}
}
lock_ReleaseWrite(&smb_rctLock);
-
+ FreeNCB(ncbp);
TlsFree(smb_TlsRequestSlot);
}
if (lock)
lock_ObtainRead(&smb_rctLock);
- sprintf(output, "begin dumping smb_vc_t\n");
+ 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;
- sprintf(output, "%s vcp=0x%p, refCount=%d, flags=%d, vcID=%d, lsn=%d, uidCounter=%d, tidCounter=%d, fidCounter=%d\n",
+ 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);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
- sprintf(output, "begin dumping smb_fid_t\n");
+ 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\n",
+ 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,
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");
+ sprintf(output, "done dumping smb_fid_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
- sprintf(output, "done dumping smb_vc_t\n");
+ sprintf(output, "done dumping smb_vc_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
- sprintf(output, "begin dumping DEAD smb_vc_t\n");
+ sprintf(output, "begin dumping DEAD smb_vc_t\r\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",
+ 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);
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
- sprintf(output, "begin dumping smb_fid_t\n");
+ 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\n",
+ 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,
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");
+ sprintf(output, "done dumping smb_fid_t\r\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");
+ sprintf(output, "done dumping DEAD smb_vc_t\r\n");
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
if (lock)
lock_ReleaseRead(&smb_rctLock);
return 0;
}
+
+long smb_IsNetworkStarted(void)
+{
+ return (smb_ListenerState == SMB_LISTENER_STARTED && smbShutdownFlag == 0);
+}