static char *illegalChars = "\\/:*?\"<>|";
static int smbShutdownFlag = 0;
-static int smb_ListenerState = SMB_LISTENER_STOPPED;
+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};
/* 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);
{
lock_ObtainWrite(&smb_globalLock);
lock_ObtainMutex(&dsp->mx);
+ osi_Log3(afsd_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_Log2(afsd_logp,"smb_ReleaseDirSearch dsp 0x%p scp 0x%p", dsp, scp);
+ osi_Log3(afsd_logp,"smb_ReleaseDirSearch cookie %d dsp 0x%p scp 0x%p",
+ dsp->cookie, dsp, scp);
free(dsp);
} else {
lock_ReleaseMutex(&dsp->mx);
osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q);
if (!smb_lastDirSearchp)
smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q;
- break;
+
+ osi_Log2(afsd_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;
code = Netbios(ncbp);
if (code == NRC_BRIDGE) {
- if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1) {
- ExitThread(1);
- }
+ int lanaRemaining = 0;
- osi_Log2(smb_logp,
- "NCBLISTEN lana=%d failed with NRC_BRIDGE. Listener thread exiting.",
- ncbp->ncb_lana_num, code);
+ 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);
- if (code != 0)
for (i = 0; i < lana_list.length; i++) {
- if (lana_list.lana[i] == ncbp->ncb_lana_num) {
- lana_list.lana[i] = 255;
- break;
- }
+ 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) {
+ smb_ListenerState = SMB_LISTENER_STOPPED;
+ smb_LANadapter = -1;
+ lana_list.length = 0;
}
- return;
- } else if (code != 0)
- {
+ FreeNCB(ncbp);
+ return;
+ } else if (code != 0) {
char tbuffer[256];
/* terminate silently if shutdown flag is set */
}
/* initialize Netbios */
-void smb_NetbiosInit()
+int smb_NetbiosInit(void)
{
NCB *ncbp;
int i, lana, code, l;
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;
}
/* we're done with the NCB now */
FreeNCB(ncbp);
+
+ return (lana_list.length > 0 ? 1 : 0);
}
void smb_StartListeners()
void smb_RestartListeners()
{
- if (smb_ListenerState == SMB_LISTENER_STARTED)
- return;
+ if (!powerStateSuspended && smb_ListenerState == SMB_LISTENER_STOPPED) {
+ if (smb_NetbiosInit())
+ smb_StartListeners();
+ }
+}
- 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_StopListeners()
+void smb_StopListeners(void)
{
NCB *ncbp;
-#ifdef DJGPP
- dos_ptr dos_ncb;
-#endif /* DJGPP */
- int lana, code, l;
+ int lana, l;
if (smb_ListenerState == SMB_LISTENER_STOPPED)
return;
for (l = 0; l < lana_list.length; l++) {
lana = lana_list.lana[l];
- memset(ncbp, 0, sizeof(*ncbp));
- ncbp->ncb_command = NCBDELNAME;
- ncbp->ncb_lana_num = lana;
- memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
-#ifndef DJGPP
- code = Netbios(ncbp);
-#else /* DJGPP */
- code = Netbios(ncbp, dos_ncb);
-#endif /* !DJGPP */
-
- afsi_log("Netbios NCBDELNAME lana=%d code=%d retcode=%d complete=%d",
- lana, code, ncbp->ncb_retcode, ncbp->ncb_cmd_cplt);
+ if (lana != 255) {
+ smb_StopListener(ncbp, lana);
- /* 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_list.lana[l];
- code = Netbios(ncbp);
- if (code == 0)
- code = ncbp->ncb_retcode;
- if (code != 0) {
- afsi_log("Netbios NCBRESET lana %d error code %d", lana_list.lana[l], code);
- } else {
- afsi_log("Netbios NCBRESET lana %d succeeded", lana_list.lana[l]);
- }
-
- /* mark the adapter invalid */
- lana_list.lana[l] = 255; /* invalid 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 */
}
return 0;
}
-long smb_ReceiveTran2FindFirst(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
-{
- osi_Log0(smb_logp,"ReceiveTran2FindFirst - NOT_SUPPORTED");
- return CM_ERROR_BADOP;
-}
-
-long smb_ReceiveTran2FindNext(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp)
-{
- osi_Log0(smb_logp,"ReceiveTran2FindNext - NOT_SUPPORTED");
- return CM_ERROR_BADOP;
-}
-
long smb_ReceiveTran2QFSInfoFid(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op)
{
unsigned short fid;
}
#endif /* USE_OLD_MATCHING */
+/* smb_ReceiveTran2SearchDir implements both
+ * Tran2_Find_First and Tran2_Find_Next
+ */
+#define TRAN2_FIND_FLAG_CLOSE_SEARCH 0x01
+#define TRAN2_FIND_FLAG_CLOSE_SEARCH_IF_END 0x02
+#define TRAN2_FIND_FLAG_RETURN_RESUME_KEYS 0x04
+#define TRAN2_FIND_FLAG_CONTINUE_SEARCH 0x08
+#define TRAN2_FIND_FLAG_BACKUP_INTENT 0x10
+
long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx)
{
int attribute;
}
if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO)
- searchFlags &= ~4; /* no resume keys */
+ searchFlags &= ~TRAN2_FIND_FLAG_RETURN_RESUME_KEYS; /* no resume keys */
dirListPatchesp = NULL;
bytesInBuffer = 0;
while (1) {
op = origOp;
- if (searchFlags & 4)
+ if (searchFlags & TRAN2_FIND_FLAG_RETURN_RESUME_KEYS)
/* skip over resume key */
op += 4;
if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO)
ohbytes += 26; /* Short name & length */
- if (searchFlags & 4) {
+ if (searchFlags & TRAN2_FIND_FLAG_RETURN_RESUME_KEYS) {
ohbytes += 4; /* if resume key required */
}
curPatchp->dep = dep;
}
- if (searchFlags & 4)
+ if (searchFlags & TRAN2_FIND_FLAG_RETURN_RESUME_KEYS)
/* put out resume key */
*((u_long *)origOp) = nextEntryCookie;
* we're supposed to close the search if we're done, and we're done,
* or if something went wrong, close the search.
*/
- /* ((searchFlags & 1) || ((searchFlags & 2) && eos) */
- if ((searchFlags & 1) || (returnedNames == 0) ||
- ((searchFlags & 2) && eos) || code != 0)
+ if ((searchFlags & TRAN2_FIND_FLAG_CLOSE_SEARCH) ||
+ (returnedNames == 0) ||
+ ((searchFlags & TRAN2_FIND_FLAG_CLOSE_SEARCH_IF_END) && eos) ||
+ code != 0)
smb_DeleteDirSearch(dsp);
+
if (code)
smb_SendTran2Error(vcp, p, opx, code);
else
BOOL foundscp;
cm_req_t req;
int created = 0;
+ cm_lock_data_t *ldp = NULL;
cm_InitReq(&req);
* scp is NULL.
*/
if (code == 0 && !treeCreate) {
- code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req);
+ code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req, &ldp);
if (code) {
if (dscp)
cm_ReleaseSCache(dscp);
if (createDisp == FILE_CREATE) {
/* oops, file shouldn't be there */
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
if (dscp)
cm_ReleaseSCache(dscp);
if (scp)
*/
osi_Log2(smb_logp, "symlink vp %x to vp %x",
scp, targetScp);
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
cm_ReleaseSCache(scp);
scp = targetScp;
- }
+ code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req, &ldp);
+ if (code) {
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+ if (scp)
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return code;
+ }
+ }
}
code = cm_SetAttr(scp, &setAttr, userp, &req);
openAction = 3; /* truncated existing file */
if (code) {
/* something went wrong creating or truncating the file */
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
if (scp)
cm_ReleaseSCache(scp);
if (dscp)
* we'll just use the symlink anyway.
*/
osi_Log2(smb_logp, "symlink vp %x to vp %x", scp, targetScp);
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
cm_ReleaseSCache(scp);
scp = targetScp;
}
}
if (scp->fileType != CM_SCACHETYPE_FILE) {
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
if (dscp)
cm_ReleaseSCache(dscp);
cm_ReleaseSCache(scp);
/* (only applies to single component case) */
if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
cm_ReleaseSCache(scp);
if (dscp)
cm_ReleaseSCache(dscp);
lock_ReleaseMutex(&scp->mx);
if (code) {
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
cm_ReleaseSCache(scp);
if (dscp)
cm_ReleaseSCache(dscp);
- cm_ReleaseUser(userp);
- /* shouldn't this be smb_CloseFID() fidp->flags = SMB_FID_DELETE; */
+ cm_ReleaseUser(userp);
+ /* Shouldn't this be smb_CloseFID()? fidp->flags = SMB_FID_DELETE; */
smb_CloseFID(vcp, fidp, NULL, 0);
- smb_ReleaseFID(fidp);
+ smb_ReleaseFID(fidp);
free(realPathp);
return code;
}
}
+ /* Now its safe to release the file server lock obtained by cm_CheckNTOpen() */
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
+
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp; /* Hold transfered to fidp->scp and no longer needed */
char *outData;
cm_req_t req;
int created = 0;
+ cm_lock_data_t *ldp = NULL;
cm_InitReq(&req);
* scp is NULL.
*/
if (code == 0) {
- code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp,
- &req);
+ code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req, &ldp);
if (code) {
if (dscp)
cm_ReleaseSCache(dscp);
if (createDisp == FILE_CREATE) {
/* oops, file shouldn't be there */
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
if (dscp)
cm_ReleaseSCache(dscp);
cm_ReleaseSCache(scp);
*/
osi_Log2(smb_logp, "symlink vp %x to vp %x",
scp, targetScp);
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
cm_ReleaseSCache(scp);
scp = targetScp;
+ code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp, &req, &ldp);
+ if (code) {
+ if (dscp)
+ cm_ReleaseSCache(dscp);
+ if (scp)
+ cm_ReleaseSCache(scp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return code;
+ }
}
}
code = cm_SetAttr(scp, &setAttr, userp, &req);
if (code) {
/* something went wrong creating or truncating the file */
- if (scp)
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
+ if (scp)
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
*/
osi_Log2(smb_logp, "symlink vp %x to vp %x",
scp, targetScp);
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
cm_ReleaseSCache(scp);
scp = targetScp;
}
}
if (scp->fileType != CM_SCACHETYPE_FILE) {
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
}
if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
free(realPathp);
lock_ReleaseMutex(&scp->mx);
if (code) {
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- /* Shouldn't this be smb_CloseFID()? fidp->flags = SMB_FID_DELETE; */
+ /* Shouldn't this be smb_CloseFID()? fidp->flags = SMB_FID_DELETE; */
smb_CloseFID(vcp, fidp, NULL, 0);
- smb_ReleaseFID(fidp);
- free(realPathp);
+ smb_ReleaseFID(fidp);
+ free(realPathp);
return CM_ERROR_SHARING_VIOLATION;
}
}
+ /* Now its safe to drop the file server lock obtained by cm_CheckNTOpen() */
+ if (ldp)
+ cm_CheckNTOpenDone(scp, userp, &req, &ldp);
+
lock_ObtainMutex(&fidp->mx);
/* save a pointer to the vnode */
fidp->scp = scp;
smb_packet_t *outp)
{
smb_packet_t *savedPacketp;
- ULONG filter; USHORT fid, watchtree;
+ ULONG filter;
+ USHORT fid, watchtree;
smb_fid_t *fidp;
cm_scache_t *scp;
filter = smb_GetSMBParm(inp, 19) |
(smb_GetSMBParm(inp, 20) << 16);
fid = smb_GetSMBParm(inp, 21);
- watchtree = smb_GetSMBParm(inp, 22) && 0xffff; /* TODO: should this be 0xff ? */
+ watchtree = (smb_GetSMBParm(inp, 22) & 0xff) ? 1 : 0;
fidp = smb_FindFID(vcp, fid, 0);
if (!fidp) {
return CM_ERROR_BADFD;
}
+ /* Create a copy of the Directory Watch Packet to use when sending the
+ * notification if in the future a matching change is detected.
+ */
savedPacketp = smb_CopyPacket(inp);
smb_HoldVC(vcp);
if (savedPacketp->vcp)
smb_ReleaseVC(savedPacketp->vcp);
savedPacketp->vcp = vcp;
+
+ /* Add the watch to the list of events to send notifications for */
lock_ObtainMutex(&smb_Dir_Watch_Lock);
savedPacketp->nextp = smb_Directory_Watches;
smb_Directory_Watches = savedPacketp;
lock_ReleaseMutex(&smb_Dir_Watch_Lock);
- osi_Log4(smb_logp, "Request for NotifyChange filter 0x%x fid %d wtree %d file %s",
- filter, fid, watchtree, osi_LogSaveString(smb_logp, fidp->NTopen_wholepathp));
-
scp = fidp->scp;
- osi_Log2(afsd_logp,"smb_ReceiveNTTranNotifyChange fidp 0x%p scp 0x%p", fidp, scp);
+ osi_Log3(afsd_logp,"smb_ReceiveNTTranNotifyChange fidp 0x%p scp 0x%p file \"%s\"",
+ fidp, scp, osi_LogSaveString(smb_logp, fidp->NTopen_wholepathp));
+ osi_Log3(smb_logp, "Request for NotifyChange filter 0x%x fid %d wtree %d",
+ filter, fid, watchtree);
+ if (filter & FILE_NOTIFY_CHANGE_FILE_NAME)
+ osi_Log0(smb_logp, " Notify Change File Name");
+ if (filter & FILE_NOTIFY_CHANGE_DIR_NAME)
+ osi_Log0(smb_logp, " Notify Change Directory Name");
+ if (filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)
+ osi_Log0(smb_logp, " Notify Change Attributes");
+ if (filter & FILE_NOTIFY_CHANGE_SIZE)
+ osi_Log0(smb_logp, " Notify Change Size");
+ if (filter & FILE_NOTIFY_CHANGE_LAST_WRITE)
+ osi_Log0(smb_logp, " Notify Change Last Write");
+ if (filter & FILE_NOTIFY_CHANGE_LAST_ACCESS)
+ osi_Log0(smb_logp, " Notify Change Last Access");
+ if (filter & FILE_NOTIFY_CHANGE_CREATION)
+ osi_Log0(smb_logp, " Notify Change Creation");
+ if (filter & FILE_NOTIFY_CHANGE_EA)
+ osi_Log0(smb_logp, " Notify Change Extended Attributes");
+ if (filter & FILE_NOTIFY_CHANGE_SECURITY)
+ osi_Log0(smb_logp, " Notify Change Security");
+ if (filter & FILE_NOTIFY_CHANGE_STREAM_NAME)
+ osi_Log0(smb_logp, " Notify Change Stream Name");
+ if (filter & FILE_NOTIFY_CHANGE_STREAM_SIZE)
+ osi_Log0(smb_logp, " Notify Change Stream Size");
+ if (filter & FILE_NOTIFY_CHANGE_STREAM_WRITE)
+ osi_Log0(smb_logp, " Notify Change Stream Write");
+
lock_ObtainMutex(&scp->mx);
if (watchtree)
scp->flags |= CM_SCACHEFLAG_WATCHEDSUBTREE;
*
* If we don't know the file name (i.e. a callback break), filename is
* NULL, and we return a zero-length list.
+ *
+ * At present there is not a single call to smb_NotifyChange that
+ * has the isDirectParent parameter set to FALSE.
*/
void smb_NotifyChange(DWORD action, DWORD notifyFilter,
cm_scache_t *dscp, char *filename, char *otherFilename,
otherAction = FILE_ACTION_RENAMED_NEW_NAME;
}
- osi_Log2(smb_logp,"in smb_NotifyChange for file [%s] dscp [%x]",
- osi_LogSaveString(smb_logp,filename),dscp);
+ osi_Log4(smb_logp,"in smb_NotifyChange for file [%s] dscp [%p] notification 0x%x parent %d",
+ osi_LogSaveString(smb_logp,filename),dscp, notifyFilter, isDirectParent);
+ if (action == 0)
+ osi_Log0(smb_logp," FILE_ACTION_NONE");
+ if (action == FILE_ACTION_ADDED)
+ osi_Log0(smb_logp," FILE_ACTION_ADDED");
+ if (action == FILE_ACTION_REMOVED)
+ osi_Log0(smb_logp," FILE_ACTION_REMOVED");
+ if (action == FILE_ACTION_MODIFIED)
+ osi_Log0(smb_logp," FILE_ACTION_MODIFIED");
+ if (action == FILE_ACTION_RENAMED_OLD_NAME)
+ osi_Log0(smb_logp," FILE_ACTION_RENAMED_OLD_NAME");
+ if (action == FILE_ACTION_RENAMED_NEW_NAME)
+ osi_Log0(smb_logp," FILE_ACTION_RENAMED_NEW_NAME");
lock_ObtainMutex(&smb_Dir_Watch_Lock);
watch = smb_Directory_Watches;
filter = smb_GetSMBParm(watch, 19)
| (smb_GetSMBParm(watch, 20) << 16);
fid = smb_GetSMBParm(watch, 21);
- wtree = smb_GetSMBParm(watch, 22) & 0xffff; /* TODO: should this be 0xff ? */
+ wtree = (smb_GetSMBParm(watch, 22) & 0xff) ? 1 : 0;
+
maxLen = smb_GetSMBOffsetParm(watch, 5, 1)
| (smb_GetSMBOffsetParm(watch, 6, 1) << 16);
/*
- * Strange hack - bug in NT Client and NT Server that we
- * must emulate?
+ * Strange hack - bug in NT Client and NT Server that we must emulate?
*/
- if (filter == 3 && wtree)
- filter = 0x17;
+ if ((filter == (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME)) && wtree)
+ filter |= FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES;
fidp = smb_FindFID(watch->vcp, fid, 0);
if (!fidp) {
- osi_Log1(smb_logp," no fidp for fid[%d]",fid);
+ osi_Log2(smb_logp," no fidp for fid[%d] in vcp 0x%p",fid, watch->vcp);
lastWatch = watch;
watch = watch->nextp;
continue;
if (fidp->scp != dscp
|| (filter & notifyFilter) == 0
|| (!isDirectParent && !wtree)) {
- osi_Log1(smb_logp," passing fidp->scp[%x]", fidp->scp);
+ osi_Log1(smb_logp," skipping fidp->scp[%x]", fidp->scp);
smb_ReleaseFID(fidp);
lastWatch = watch;
watch = watch->nextp;
osi_Log4(smb_logp,
"Sending Change Notification for fid %d filter 0x%x wtree %d file %s",
fid, filter, wtree, osi_LogSaveString(smb_logp, filename));
-
+ if (filter & FILE_NOTIFY_CHANGE_FILE_NAME)
+ osi_Log0(smb_logp, " Notify Change File Name");
+ if (filter & FILE_NOTIFY_CHANGE_DIR_NAME)
+ osi_Log0(smb_logp, " Notify Change Directory Name");
+ if (filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)
+ osi_Log0(smb_logp, " Notify Change Attributes");
+ if (filter & FILE_NOTIFY_CHANGE_SIZE)
+ osi_Log0(smb_logp, " Notify Change Size");
+ if (filter & FILE_NOTIFY_CHANGE_LAST_WRITE)
+ osi_Log0(smb_logp, " Notify Change Last Write");
+ if (filter & FILE_NOTIFY_CHANGE_LAST_ACCESS)
+ osi_Log0(smb_logp, " Notify Change Last Access");
+ if (filter & FILE_NOTIFY_CHANGE_CREATION)
+ osi_Log0(smb_logp, " Notify Change Creation");
+ if (filter & FILE_NOTIFY_CHANGE_EA)
+ osi_Log0(smb_logp, " Notify Change Extended Attributes");
+ if (filter & FILE_NOTIFY_CHANGE_SECURITY)
+ osi_Log0(smb_logp, " Notify Change Security");
+ if (filter & FILE_NOTIFY_CHANGE_STREAM_NAME)
+ osi_Log0(smb_logp, " Notify Change Stream Name");
+ if (filter & FILE_NOTIFY_CHANGE_STREAM_SIZE)
+ osi_Log0(smb_logp, " Notify Change Stream Size");
+ if (filter & FILE_NOTIFY_CHANGE_STREAM_WRITE)
+ osi_Log0(smb_logp, " Notify Change Stream Write");
+
+ /* A watch can only be notified once. Remove it from the list */
nextWatch = watch->nextp;
if (watch == smb_Directory_Watches)
smb_Directory_Watches = nextWatch;