#include <afs/param.h>
#include <afs/stds.h>
-#ifndef DJGPP
#include <windows.h>
+#pragma warning(push)
+#pragma warning(disable: 4005)
#include <ntstatus.h>
-#else
-#include <sys/timeb.h>
-#include <tzfile.h>
-#endif /* !DJGPP */
+#pragma warning(pop)
#include <stddef.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
#include <time.h>
+#include "afsd.h"
#include <osi.h>
#include <rx\rx.h>
#include <rx/rx_prototypes.h>
-
-#include "afsd.h"
#include <WINNT\afsreg.h>
#include "smb.h"
#include "lanahelper.h"
+#define STRSAFE_NO_DEPRECATE
+#include <strsafe.h>
+
/* These characters are illegal in Windows filenames */
-static char *illegalChars = "\\/:*?\"<>|";
-BOOL isWindows2000 = FALSE;
+static clientchar_t *illegalChars = _C("\\/:*?\"<>|");
-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};
osi_rwlock_t smb_globalLock;
osi_rwlock_t smb_rctLock;
osi_mutex_t smb_ListenerLock;
-
-char smb_LANadapter;
+osi_mutex_t smb_StartedLock;
+
+unsigned char smb_LANadapter = LANA_INVALID;
unsigned char smb_sharename[NCBNAMSZ+1] = {0};
+int smb_LanAdapterChangeDetected = 0;
+afs_uint32 smb_AsyncStore = 1;
+afs_uint32 smb_AsyncStoreSize = CM_CONFIGDEFAULT_ASYNCSTORESIZE;
+
+BOOL isGateway = FALSE;
/* for debugging */
long smb_maxObsConcurrentCalls=0;
smb_packet_t *smb_packetFreeListp;
smb_ncb_t *smb_ncbFreeListp;
-int smb_NumServerThreads;
+afs_uint32 smb_NumServerThreads;
-int numNCBs, numSessions, numVCs;
+afs_uint32 numNCBs, numSessions, numVCs;
int smb_maxVCPerServer;
int smb_maxMpxRequests;
EVENT_HANDLE **NCBreturns;
EVENT_HANDLE **NCBShutdown;
EVENT_HANDLE *smb_ServerShutdown;
+EVENT_HANDLE ListenerShutdown[256];
DWORD NCBsessions[NCB_MAX];
NCB *NCBs[NCB_MAX];
struct smb_packet *bufs[NCB_MAX];
int lanas[SESSION_MAX];
BOOL dead_sessions[SESSION_MAX];
LANA_ENUM lana_list;
-
/* for raw I/O */
osi_mutex_t smb_RawBufLock;
-#ifdef DJGPP
-#define SMB_RAW_BUFS 4
-dos_ptr smb_RawBufs;
-int smb_RawBufSel[SMB_RAW_BUFS];
-#else
char *smb_RawBufs;
-#endif /* DJGPP */
#define SMB_MASKFLAG_TILDE 1
#define SMB_MASKFLAG_CASEFOLD 2
/* for raw write */
typedef struct raw_write_cont {
- long code;
- osi_hyper_t offset;
- long count;
-#ifndef DJGPP
- char *buf;
-#else
- dos_ptr buf;
-#endif /* DJGPP */
- int writeMode;
- long alreadyWritten;
+ long code;
+ osi_hyper_t offset;
+ long count;
+ char *buf;
+ int writeMode;
+ long alreadyWritten;
} raw_write_cont_t;
/* dir search stuff */
/* hide dot files? */
int smb_hideDotFiles;
+/* Negotiate Unicode support? */
+LONG smb_UseUnicode;
+
/* global state about V3 protocols */
int smb_useV3; /* try to negotiate V3 */
-#ifndef DJGPP
-static showErrors = 1;
+static int showErrors = 0;
/* MessageBox or something like it */
-int (_stdcall *smb_MBfunc)(HWND, LPCTSTR, LPCTSTR, UINT) = NULL;
-#endif /* DJGPP */
+int (_stdcall *smb_MBfunc)(HWND, LPCTSTR, LPCTSTR, UINT)
+= NULL;
/* GMT time info:
* Time in Unix format of midnight, 1/1/1970 local time.
/* 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();
-#ifdef DJGPP
-#ifndef AFS_WIN95_ENV
-DWORD smb_ServerExceptionFilter(void);
-#endif
-
-extern char cm_HostName[];
-extern char cm_confDir[];
-#endif
-
-#ifdef DJGPP
-#define LPTSTR char *
-#define GetComputerName(str, sizep) \
- strcpy((str), cm_HostName); \
- *(sizep) = strlen(cm_HostName)
-#endif /* DJGPP */
+int smb_NetbiosInit(int);
#ifdef LOG_PACKET
void smb_LogPacket(smb_packet_t *packet);
#endif /* LOG_PACKET */
-
-char smb_ServerDomainName[MAX_COMPUTERNAME_LENGTH + 1] = ""; /* domain name */
+
+clientchar_t smb_ServerDomainName[MAX_COMPUTERNAME_LENGTH + 1] = _C(""); /* domain name */
int smb_ServerDomainNameLength = 0;
-char smb_ServerOS[] = "Windows 5.0"; /* Faux OS String */
-int smb_ServerOSLength = sizeof(smb_ServerOS);
-char smb_ServerLanManager[] = "Windows 2000 LAN Manager"; /* Faux LAN Manager string */
-int smb_ServerLanManagerLength = sizeof(smb_ServerLanManager);
+clientchar_t smb_ServerOS[] = _C("Windows 5.0"); /* Faux OS String */
+int smb_ServerOSLength = lengthof(smb_ServerOS);
+clientchar_t smb_ServerLanManager[] = _C("Windows 2000 LAN Manager"); /* Faux LAN Manager string */
+int smb_ServerLanManagerLength = lengthof(smb_ServerLanManager);
/* Faux server GUID. This is never checked. */
GUID smb_ServerGUID = { 0x40015cb8, 0x058a, 0x44fc, { 0xae, 0x7e, 0xbb, 0x29, 0x52, 0xee, 0x7e, 0xff }};
void smb_SetRequestStartTime()
{
- time_t * tp = malloc(sizeof(time_t));
+ time_t * tp = TlsGetValue(smb_TlsRequestSlot);
+ if (!tp)
+ tp = malloc(sizeof(time_t));
if (tp) {
*tp = osi_Time();
time_t now = osi_Time();
/* Give one priority boost for each 15 seconds */
- SetThreadPriority(GetCurrentThread(), (now - *tp) / 15);
+ SetThreadPriority(GetCurrentThread(), (int)((now - *tp) / 15));
}
}
return "(2d)ReceiveV3OpenX";
case 0x2e:
return "(2e)ReceiveV3ReadX";
+ case 0x2f:
+ return "(2f)ReceiveV3WriteX";
case 0x32:
return "(32)ReceiveV3Tran2A";
case 0x33:
default:
return "unknown SMB op-2";
case 0:
- return "S(00)CreateFile";
+ return "S(00)CreateFile_ReceiveTran2Open";
case 1:
- return "S(01)FindFirst";
+ return "S(01)FindFirst_ReceiveTran2SearchDir";
case 2:
- return "S(02)FindNext"; /* FindNext */
+ return "S(02)FindNext_ReceiveTran2SearchDir"; /* FindNext */
case 3:
return "S(03)QueryFileSystem_ReceiveTran2QFSInfo";
case 4:
- return "S(04)??";
+ return "S(04)SetFileSystem_ReceiveTran2SetFSInfo";
case 5:
- return "S(05)QueryFileInfo_ReceiveTran2QPathInfo";
+ return "S(05)QueryPathInfo_ReceiveTran2QPathInfo";
case 6:
- return "S(06)SetFileInfo_ReceiveTran2SetPathInfo";
+ return "S(06)SetPathInfo_ReceiveTran2SetPathInfo";
case 7:
- return "S(07)SetInfoHandle_ReceiveTran2QFileInfo";
+ return "S(07)QueryFileInfo_ReceiveTran2QFileInfo";
case 8:
- return "S(08)??_ReceiveTran2SetFileInfo";
+ return "S(08)SetFileInfo_ReceiveTran2SetFileInfo";
case 9:
- return "S(09)??_ReceiveTran2FSCTL";
+ return "S(09)_ReceiveTran2FSCTL";
case 10:
return "S(0a)_ReceiveTran2IOCTL";
case 11:
return "S(0d)_ReceiveTran2CreateDirectory";
case 14:
return "S(0e)_ReceiveTran2SessionSetup";
+ case 15:
+ return "S(0f)_QueryFileSystemInformationFid";
case 16:
return "S(10)_ReceiveTran2GetDfsReferral";
case 17:
/* Check if the named file/dir is a dotfile/dotdir */
/* String pointed to by lastComp can have leading slashes, but otherwise should have
no other patch components */
-unsigned int smb_IsDotFile(char *lastComp) {
- char *s;
+unsigned int smb_IsDotFile(clientchar_t *lastComp) {
+ clientchar_t *s;
+
if(lastComp) {
/* skip over slashes */
for(s=lastComp;*s && (*s == '\\' || *s == '/'); s++);
return 0;
/* nulls, curdir and parent dir doesn't count */
- if (!*s)
+ if (!*s)
return 0;
- if (*s == '.') {
+ if (*s == _C('.')) {
if (!*(s + 1))
return 0;
- if(*(s+1) == '.' && !*(s + 2))
+ if(*(s+1) == _C('.') && !*(s + 2))
return 0;
return 1;
}
return (int)num;
}
-#ifndef DJGPP
void ShowUnixTime(char *FuncName, time_t unixTime)
{
FILETIME ft;
osi_Log1(smb_logp, "%s", osi_LogSaveString(smb_logp, msg));
}
}
-#endif /* DJGPP */
-#ifndef DJGPP
/* Determine if we are observing daylight savings time */
void GetTimeZoneInfo(BOOL *pDST, LONG *pDstBias, LONG *pBias)
{
*/
*pDST = localDST.wHour != local.wHour;
}
-#else
-/* Determine if we are observing daylight savings time */
-void GetTimeZoneInfo(BOOL *pDST, LONG *pDstBias, LONG *pBias)
-{
- struct timeb t;
-
- ftime(&t);
- *pDST = t.dstflag;
- *pDstBias = -60; /* where can this be different? */
- *pBias = t.timezone;
-}
-#endif /* DJGPP */
void CompensateForSmbClientLastWriteTimeBugs(afs_uint32 *pLastWriteTime)
}
#endif /* USE_NUMERIC_TIME_CONV */
-#ifndef DJGPP
#ifdef USE_NUMERIC_TIME_CONV
void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime)
{
SystemTimeToFileTime(&stm, largeTimep);
}
#endif /* USE_NUMERIC_TIME_CONV */
-#else /* DJGPP */
-void smb_LargeSearchTimeFromUnixTime(FILETIME *largeTimep, time_t unixTime)
-{
- /* unixTime: seconds since 1/1/1970 00:00:00 GMT */
- /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 ??? */
- LARGE_INTEGER *ft = (LARGE_INTEGER *) largeTimep;
- LARGE_INTEGER ut;
- int leap_years = 89; /* leap years betw 1/1/1601 and 1/1/1970 */
-
- /* set ft to number of 100ns intervals betw 1/1/1601 and 1/1/1970 GMT */
- *ft = ConvertLongToLargeInteger(((EPOCH_YEAR-1601) * 365 + leap_years)
- * 24 * 60);
- *ft = LargeIntegerMultiplyByLong(*ft, 60);
- *ft = LargeIntegerMultiplyByLong(*ft, 10000000);
-
- /* add unix time */
- ut = ConvertLongToLargeInteger(unixTime);
- ut = LargeIntegerMultiplyByLong(ut, 10000000);
- *ft = LargeIntegerAdd(*ft, ut);
-}
-#endif /* !DJGPP */
-#ifndef DJGPP
#ifdef USE_NUMERIC_TIME_CONV
void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep)
{
_timezone = save_timezone;
}
#endif /* USE_NUMERIC_TIME_CONV */
-#else /* DJGPP */
-void smb_UnixTimeFromLargeSearchTime(time_t *unixTimep, FILETIME *largeTimep)
-{
- /* unixTime: seconds since 1/1/1970 00:00:00 GMT */
- /* FILETIME: 100ns intervals since 1/1/1601 00:00:00 GMT? */
- LARGE_INTEGER *ft = (LARGE_INTEGER *) largeTimep;
- LARGE_INTEGER a;
- int leap_years = 89;
-
- /* set to number of 100ns intervals betw 1/1/1601 and 1/1/1970 */
- a = ConvertLongToLargeInteger(((EPOCH_YEAR-1601) * 365 + leap_years) * 24 * 60);
- a = LargeIntegerMultiplyByLong(a, 60);
- a = LargeIntegerMultiplyByLong(a, 10000000);
-
- /* subtract it from ft */
- a = LargeIntegerSubtract(*ft, a);
-
- /* divide down to seconds */
- *unixTimep = LargeIntegerDivideByLong(a, 10000000);
-}
-#endif /* !DJGPP */
void smb_SearchTimeFromUnixTime(afs_uint32 *searchTimep, time_t unixTime)
{
{
time_t diff_t = unixTime - smb_localZero;
#if defined(DEBUG) && !defined(_USE_32BIT_TIME_T)
- osi_assert(diff_t < _UI32_MAX);
+ osi_assertx(diff_t < _UI32_MAX, "time_t > _UI32_MAX");
#endif
*dosUTimep = (afs_uint32)diff_t;
}
void smb_UnixTimeFromDosUTime(time_t *unixTimep, afs_uint32 dosTime)
{
-#ifndef DJGPP
*unixTimep = dosTime + smb_localZero;
-#else /* DJGPP */
- /* dosTime seems to be already adjusted for GMT */
- *unixTimep = dosTime;
-#endif /* !DJGPP */
}
smb_vc_t *smb_FindVC(unsigned short lsn, int flags, int lana)
{
smb_vc_t *vcp;
+ lock_ObtainWrite(&smb_globalLock); /* for numVCs */
lock_ObtainWrite(&smb_rctLock);
for (vcp = smb_allVCsp; vcp; vcp=vcp->nextp) {
if (vcp->magic != SMB_VC_MAGIC)
if (!vcp && (flags & SMB_FLAG_CREATE)) {
vcp = malloc(sizeof(*vcp));
memset(vcp, 0, sizeof(*vcp));
- lock_ObtainWrite(&smb_globalLock);
vcp->vcID = ++numVCs;
- lock_ReleaseWrite(&smb_globalLock);
vcp->magic = SMB_VC_MAGIC;
vcp->refCount = 2; /* smb_allVCsp and caller */
vcp->tidCounter = 1;
*/
NTSTATUS nts = STATUS_UNSUCCESSFUL, ntsEx = STATUS_UNSUCCESSFUL;
MSV1_0_LM20_CHALLENGE_REQUEST lsaReq;
- PMSV1_0_LM20_CHALLENGE_RESPONSE lsaResp;
+ PMSV1_0_LM20_CHALLENGE_RESPONSE lsaResp = NULL;
ULONG lsaRespSize = 0;
lsaReq.MessageType = MsV1_0Lm20ChallengeRequest;
&lsaResp,
&lsaRespSize,
&ntsEx);
- if (nts != STATUS_SUCCESS)
+ if (nts != STATUS_SUCCESS || ntsEx != STATUS_SUCCESS) {
osi_Log4(smb_logp,"MsV1_0Lm20ChallengeRequest failure: nts 0x%x ntsEx 0x%x respSize is %u needs %u",
nts, ntsEx, sizeof(lsaReq), lsaRespSize);
- osi_assert(nts == STATUS_SUCCESS); /* this had better work! */
+ afsi_log("MsV1_0Lm20ChallengeRequest failure: nts 0x%x ntsEx 0x%x respSize %u",
+ nts, ntsEx, lsaRespSize);
+ }
+ osi_assertx(nts == STATUS_SUCCESS, "LsaCallAuthenticationPackage failed"); /* this had better work! */
- memcpy(vcp->encKey, lsaResp->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH);
- LsaFreeReturnBuffer(lsaResp);
+ if (ntsEx == STATUS_SUCCESS) {
+ memcpy(vcp->encKey, lsaResp->ChallengeToClient, MSV1_0_CHALLENGE_LENGTH);
+ LsaFreeReturnBuffer(lsaResp);
+ } else {
+ /*
+ * This will cause the subsequent authentication to fail but
+ * that is better than us dereferencing a NULL pointer and
+ * crashing.
+ */
+ memset(vcp->encKey, 0, MSV1_0_CHALLENGE_LENGTH);
+ }
}
else
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");
}
}
lock_ReleaseWrite(&smb_rctLock);
+ lock_ReleaseWrite(&smb_globalLock);
return vcp;
}
-int smb_IsStarMask(char *maskp)
+int smb_IsStarMask(clientchar_t *maskp)
{
int i;
- char tc;
+ clientchar_t tc;
for(i=0; i<11; i++) {
tc = *maskp++;
- if (tc == '?' || tc == '*' || tc == '>')
+ if (tc == _C('?') || tc == _C('*') || tc == _C('>'))
return 1;
- }
+ }
return 0;
}
vcp->refCount--;
if (vcp->refCount == 0) {
- if (vcp->flags & SMB_VCFLAG_ALREADYDEAD) {
- /* 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);
- } else {
- for (avcp = smb_allVCsp; avcp; avcp = avcp->nextp) {
- if (avcp == vcp)
- break;
- }
- osi_Log3(smb_logp,"VCP not dead and %sin smb_allVCsp vcp %x ref %d",
- avcp?"not ":"",vcp, vcp->refCount);
+ if (vcp->flags & SMB_VCFLAG_ALREADYDEAD) {
+ /* 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);
+ } else {
+ for (avcp = smb_allVCsp; avcp; avcp = avcp->nextp) {
+ if (avcp == vcp)
+ break;
+ }
+ osi_Log3(smb_logp,"VCP not dead and %sin smb_allVCsp vcp %x ref %d",
+ avcp?"not ":"",vcp, vcp->refCount);
#ifdef DEBUG
- GenerateMiniDump(NULL);
+ GenerateMiniDump(NULL);
#endif
- /* This is a wrong. However, I suspect that there is an undercount
- * and I don't want to release 1.4.1 in a state that will allow
- * smb_vc_t objects to be deallocated while still in the
- * smb_allVCsp list. The list is supposed to keep a reference
- * to the smb_vc_t. Put it back.
- */
- vcp->refCount++;
- }
+ /* This is a wrong. However, I suspect that there is an undercount
+ * and I don't want to release 1.4.1 in a state that will allow
+ * smb_vc_t objects to be deallocated while still in the
+ * smb_allVCsp list. The list is supposed to keep a reference
+ * to the smb_vc_t. Put it back.
+ */
+ vcp->refCount++;
+ }
+ } else if (vcp->flags & SMB_VCFLAG_ALREADYDEAD) {
+ /* The reference count is non-zero but the VC is dead.
+ * This implies that some FIDs, TIDs, etc on the VC have yet to
+ * be cleaned up. Add a reference that will be dropped by
+ * smb_CleanupDeadVC() and try to cleanup the VC again.
+ * Eventually the refCount will drop to zero when all of the
+ * active threads working with the VC end their task.
+ */
+ vcp->refCount++; /* put the refCount back */
+ lock_ReleaseWrite(&smb_rctLock);
+ smb_CleanupDeadVC(vcp);
+ lock_ObtainWrite(&smb_rctLock);
}
}
for (fidpIter = vcp->fidsp; fidpIter; fidpIter = fidpNext) {
fidpNext = (smb_fid_t *) osi_QNext(&fidpIter->q);
- if (fidpIter->delete)
+ if (fidpIter->deleteOk)
continue;
fid = fidpIter->fid;
for (tidpIter = vcp->tidsp; tidpIter; tidpIter = tidpNext) {
tidpNext = tidpIter->nextp;
- if (tidpIter->delete)
+ if (tidpIter->deleteOk)
continue;
- tidpIter->delete = 1;
+ tidpIter->deleteOk = 1;
tid = tidpIter->tid;
osi_Log2(smb_logp, " Cleanup TID %d (tidp=0x%x)", tid, tidpIter);
smb_HoldTIDNoLock(tidpIter);
- lock_ReleaseWrite(&smb_rctLock);
-
- smb_ReleaseTID(tidpIter);
-
- lock_ObtainWrite(&smb_rctLock);
+ smb_ReleaseTID(tidpIter, TRUE);
tidpNext = vcp->tidsp;
}
for (uidpIter = vcp->usersp; uidpIter; uidpIter = uidpNext) {
uidpNext = uidpIter->nextp;
- if (uidpIter->delete)
+ if (uidpIter->deleteOk)
continue;
- uidpIter->delete = 1;
+ uidpIter->deleteOk = 1;
/* do not add an additional reference count for the smb_user_t
* as the smb_vc_t already is holding a reference */
uidpNext = vcp->usersp;
}
+ lock_ObtainMutex(&vcp->mx);
+ vcp->flags &= ~SMB_VCFLAG_CLEAN_IN_PROGRESS;
+ lock_ReleaseMutex(&vcp->mx);
+
/* The vcp is now on the deadVCsp list. We intentionally drop the
* reference so that the refcount can reach 0 and we can delete it */
smb_ReleaseVCNoLock(vcp);
-
+
lock_ReleaseWrite(&smb_rctLock);
osi_Log1(smb_logp, "Finished cleaning up dead vcp 0x%x", vcp);
}
smb_tid_t *tidp;
lock_ObtainWrite(&smb_rctLock);
+ retry:
for (tidp = vcp->tidsp; tidp; tidp = tidp->nextp) {
+ if (tidp->refCount == 0 && tidp->deleteOk) {
+ tidp->refCount++;
+ smb_ReleaseTID(tidp, TRUE);
+ goto retry;
+ }
+
if (tid == tidp->tid) {
tidp->refCount++;
break;
- }
+ }
}
if (!tidp && (flags & SMB_FLAG_CREATE)) {
tidp = malloc(sizeof(*tidp));
}
lock_ReleaseWrite(&smb_rctLock);
return tidp;
-}
+}
void smb_HoldTIDNoLock(smb_tid_t *tidp)
{
tidp->refCount++;
}
-void smb_ReleaseTID(smb_tid_t *tidp)
+void smb_ReleaseTID(smb_tid_t *tidp, afs_uint32 locked)
{
smb_tid_t *tp;
smb_tid_t **ltpp;
cm_user_t *userp;
userp = NULL;
- lock_ObtainWrite(&smb_rctLock);
- osi_assert(tidp->refCount-- > 0);
- if (tidp->refCount == 0 && (tidp->delete)) {
+ if (!locked)
+ lock_ObtainWrite(&smb_rctLock);
+ osi_assertx(tidp->refCount-- > 0, "smb_tid_t refCount 0");
+ if (tidp->refCount == 0 && (tidp->deleteOk)) {
ltpp = &tidp->vcp->tidsp;
for(tp = *ltpp; tp; ltpp = &tp->nextp, tp = *ltpp) {
if (tp == tidp)
break;
}
- osi_assert(tp != NULL);
+ osi_assertx(tp != NULL, "null smb_tid_t");
*ltpp = tp->nextp;
lock_FinalizeMutex(&tidp->mx);
userp = tidp->userp; /* remember to drop ref later */
smb_ReleaseVCNoLock(tidp->vcp);
tidp->vcp = NULL;
}
- lock_ReleaseWrite(&smb_rctLock);
+ if (!locked)
+ lock_ReleaseWrite(&smb_rctLock);
if (userp)
cm_ReleaseUser(userp);
}
for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) {
if (uid == uidp->userID) {
uidp->refCount++;
- osi_Log3(smb_logp, "smb_FindUID vcp[0x%p] found-uid[%d] name[%s]",
+ osi_Log3(smb_logp, "smb_FindUID vcp[0x%p] found-uid[%d] name[%S]",
vcp, uidp->userID,
- osi_LogSaveString(smb_logp, (uidp->unp) ? uidp->unp->name : ""));
+ ((uidp->unp)? osi_LogSaveClientString(smb_logp, uidp->unp->name):_C("")));
break;
}
}
vcp->usersp = uidp;
lock_InitializeMutex(&uidp->mx, "user_t mutex");
uidp->userID = uid;
- osi_Log3(smb_logp, "smb_FindUID vcp[0x%p] new-uid[%d] name[%s]",
- vcp, uidp->userID,
- osi_LogSaveString(smb_logp,uidp->unp ? uidp->unp->name : ""));
+ osi_Log3(smb_logp, "smb_FindUID vcp[0x%p] new-uid[%d] name[%S]",
+ vcp, uidp->userID,
+ ((uidp->unp)?osi_LogSaveClientString(smb_logp,uidp->unp->name):_C("")));
}
lock_ReleaseWrite(&smb_rctLock);
return uidp;
}
-smb_username_t *smb_FindUserByName(char *usern, char *machine, afs_uint32 flags)
+smb_username_t *smb_FindUserByName(clientchar_t *usern, clientchar_t *machine,
+ afs_uint32 flags)
{
smb_username_t *unp= NULL;
lock_ObtainWrite(&smb_rctLock);
for(unp = usernamesp; unp; unp = unp->nextp) {
- if (stricmp(unp->name, usern) == 0 &&
- stricmp(unp->machine, machine) == 0) {
+ if (cm_ClientStrCmpI(unp->name, usern) == 0 &&
+ cm_ClientStrCmpI(unp->machine, machine) == 0) {
unp->refCount++;
break;
}
memset(unp, 0, sizeof(*unp));
unp->refCount = 1;
unp->nextp = usernamesp;
- unp->name = strdup(usern);
- unp->machine = strdup(machine);
+ unp->name = cm_ClientStrDup(usern);
+ unp->machine = cm_ClientStrDup(machine);
usernamesp = unp;
lock_InitializeMutex(&unp->mx, "username_t mutex");
if (flags & SMB_FLAG_AFSLOGON)
return unp;
}
-smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, char *usern)
+smb_user_t *smb_FindUserByNameThisSession(smb_vc_t *vcp, clientchar_t *usern)
{
smb_user_t *uidp= NULL;
for(uidp = vcp->usersp; uidp; uidp = uidp->nextp) {
if (!uidp->unp)
continue;
- if (stricmp(uidp->unp->name, usern) == 0) {
+ if (cm_stricmp_utf16(uidp->unp->name, usern) == 0) {
uidp->refCount++;
- osi_Log3(smb_logp,"smb_FindUserByNameThisSession vcp[0x%p] uid[%d] match-name[%s]",
- vcp,uidp->userID,osi_LogSaveString(smb_logp,usern));
+ osi_Log3(smb_logp,"smb_FindUserByNameThisSession vcp[0x%p] uid[%d] match-name[%S]",
+ vcp,uidp->userID,osi_LogSaveClientString(smb_logp,usern));
break;
} else
continue;
time_t now = osi_Time();
lock_ObtainWrite(&smb_rctLock);
- osi_assert(unp->refCount-- > 0);
+ osi_assertx(unp->refCount-- > 0, "smb_username_t refCount 0");
if (unp->refCount == 0 && !(unp->flags & SMB_USERNAMEFLAG_AFSLOGON) &&
(unp->flags & SMB_USERNAMEFLAG_LOGOFF)) {
lupp = &usernamesp;
if (up == unp)
break;
}
- osi_assert(up != NULL);
+ osi_assertx(up != NULL, "null smb_username_t");
*lupp = up->nextp;
up->nextp = NULL; /* do not remove this */
lock_FinalizeMutex(&unp->mx);
free(unp->name);
free(unp->machine);
free(unp);
- }
+ }
lock_ReleaseWrite(&smb_rctLock);
-
- if (userp) {
+ if (userp)
cm_ReleaseUser(userp);
- }
}
void smb_HoldUIDNoLock(smb_user_t *uidp)
smb_username_t *unp = NULL;
lock_ObtainWrite(&smb_rctLock);
- osi_assert(uidp->refCount-- > 0);
+ osi_assertx(uidp->refCount-- > 0, "smb_user_t refCount 0");
if (uidp->refCount == 0) {
lupp = &uidp->vcp->usersp;
for(up = *lupp; up; lupp = &up->nextp, up = *lupp) {
if (up == uidp)
break;
}
- osi_assert(up != NULL);
+ osi_assertx(up != NULL, "null smb_user_t");
*lupp = up->nextp;
lock_FinalizeMutex(&uidp->mx);
unp = uidp->unp;
* Return a pointer to a pathname extracted from a TID structure. The
* TID structure is not held; assume it won't go away.
*/
-long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, char ** treepath)
+long smb_LookupTIDPath(smb_vc_t *vcp, unsigned short tid, clientchar_t ** treepath)
{
smb_tid_t *tidp;
long code = 0;
/* tidp->pathname would be NULL, but that's fine */
}
*treepath = tidp->pathname;
- smb_ReleaseTID(tidp);
+ smb_ReleaseTID(tidp, FALSE);
}
return code;
}
retry:
for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) {
+ if (fidp->refCount == 0 && fidp->deleteOk) {
+ fidp->refCount++;
+ lock_ReleaseWrite(&smb_rctLock);
+ smb_ReleaseFID(fidp);
+ lock_ObtainWrite(&smb_rctLock);
+ goto retry;
+ }
if (fid == fidp->fid) {
if (newFid) {
fid++;
return fidp;
}
+smb_fid_t *smb_FindFIDByScache(smb_vc_t *vcp, cm_scache_t * scp)
+{
+ smb_fid_t *fidp = NULL;
+ int newFid = 0;
+
+ if (!scp)
+ return NULL;
+
+ lock_ObtainWrite(&smb_rctLock);
+ for(fidp = vcp->fidsp; fidp; fidp = (smb_fid_t *) osi_QNext(&fidp->q)) {
+ if (scp == fidp->scp) {
+ fidp->refCount++;
+ break;
+ }
+ }
+ lock_ReleaseWrite(&smb_rctLock);
+ return fidp;
+}
+
void smb_HoldFIDNoLock(smb_fid_t *fidp)
{
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;
lock_ObtainMutex(&fidp->mx);
lock_ObtainWrite(&smb_rctLock);
- osi_assert(fidp->refCount-- > 0);
- if (fidp->refCount == 0 && (fidp->delete)) {
+ osi_assertx(fidp->refCount-- > 0, "smb_fid_t refCount 0");
+ if (fidp->refCount == 0 && (fidp->deleteOk)) {
vcp = fidp->vcp;
fidp->vcp = NULL;
scp = fidp->scp; /* release after lock is released */
- fidp->scp = NULL;
+ if (scp) {
+ lock_ObtainWrite(&scp->rw);
+ scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
+ lock_ReleaseWrite(&scp->rw);
+ osi_Log2(smb_logp,"smb_ReleaseFID fidp 0x%p scp 0x%p", fidp, scp);
+ fidp->scp = NULL;
+ }
userp = fidp->userp;
fidp->userp = NULL;
if (ioctlp) {
if (ioctlp->prefix)
cm_FreeSpace(ioctlp->prefix);
- if (ioctlp->inAllocp)
- free(ioctlp->inAllocp);
- if (ioctlp->outAllocp)
- free(ioctlp->outAllocp);
+ if (ioctlp->ioctl.inAllocp)
+ free(ioctlp->ioctl.inAllocp);
+ if (ioctlp->ioctl.outAllocp)
+ free(ioctlp->ioctl.outAllocp);
free(ioctlp);
}
lock_ReleaseMutex(&fidp->mx);
* Case-insensitive search for one string in another;
* used to find variable names in submount pathnames.
*/
-static char *smb_stristr(char *str1, char *str2)
+static clientchar_t *smb_stristr(clientchar_t *str1, clientchar_t *str2)
{
- char *cursor;
+ clientchar_t *cursor;
for (cursor = str1; *cursor; cursor++)
- if (stricmp(cursor, str2) == 0)
+ if (cm_ClientStrCmpI(cursor, str2) == 0)
return cursor;
return NULL;
* name has been identified by smb_stristr() and is in substr. Variable name
* length (plus one) is in substr_size. Variable value is in newstr.
*/
-static void smb_subst(char *str1, char *substr, unsigned int substr_size,
- char *newstr)
+static void smb_subst(clientchar_t *str1, int cchstr1, clientchar_t *substr,
+ unsigned int substr_size, clientchar_t *newstr)
{
- char temp[1024];
+ clientchar_t temp[1024];
- strcpy(temp, substr + substr_size - 1);
- strcpy(substr, newstr);
- strcat(str1, temp);
-}
-
-char VNUserName[] = "%USERNAME%";
-char VNLCUserName[] = "%LCUSERNAME%";
-char VNComputerName[] = "%COMPUTERNAME%";
-char VNLCComputerName[] = "%LCCOMPUTERNAME%";
-
-#ifdef DJGPP
-/* List available shares */
-int smb_ListShares()
-{
- char sbmtpath[256];
- char pathName[256];
- char shareBuf[4096];
- int num_shares=0;
- char *this_share;
- int len;
- char *p;
- int print_afs = 0;
- int code;
-
- /*strcpy(shareNameList[num_shares], "all");
- strcpy(pathNameList[num_shares++], "/afs");*/
- fprintf(stderr, "The following shares are available:\n");
- fprintf(stderr, "Share Name (AFS Path)\n");
- fprintf(stderr, "---------------------\n");
- fprintf(stderr, "\\\\%s\\%-16s (%s)\n", smb_localNamep, "ALL", cm_mountRoot);
-
-#ifndef DJGPP
- code = GetWindowsDirectory(sbmtpath, sizeof(sbmtpath));
- if (code == 0 || code > sizeof(sbmtpath)) return -1;
-#else
- strcpy(sbmtpath, cm_confDir);
-#endif /* !DJGPP */
- strcat(sbmtpath, "/afsdsbmt.ini");
- len = GetPrivateProfileString("AFS Submounts", NULL, NULL,
- shareBuf, sizeof(shareBuf),
- sbmtpath);
- if (len == 0) {
- return num_shares;
- }
-
- this_share = shareBuf;
- do
- {
- print_afs = 0;
- /*strcpy(shareNameList[num_shares], this_share);*/
- len = GetPrivateProfileString("AFS Submounts", this_share,
- NULL,
- pathName, 256,
- sbmtpath);
- if (!len)
- return num_shares;
- p = pathName;
- if (strncmp(p, cm_mountRoot, strlen(cm_mountRoot)) != 0)
- print_afs = 1;
- while (*p) {
- if (*p == '\\') *p = '/'; /* change to / */
- p++;
- }
-
- fprintf(stderr, "\\\\%s\\%-16s (%s%s)\n",
- smb_localNamep, this_share, (print_afs ? cm_mountRoot : "\0"),
- pathName);
- num_shares++;
- while (*this_share != 0) this_share++; /* find next NUL */
- this_share++; /* skip past the NUL */
- } while (*this_share != 0); /* stop at final NUL */
-
- return num_shares;
+ cm_ClientStrCpy(temp, lengthof(temp), substr + substr_size - 1);
+ cm_ClientStrCpy(substr, cchstr1 - (substr - str1), newstr);
+ cm_ClientStrCat(str1, cchstr1, temp);
}
-#endif /* DJGPP */
+
+clientchar_t VNUserName[] = _C("%USERNAME%");
+clientchar_t VNLCUserName[] = _C("%LCUSERNAME%");
+clientchar_t VNComputerName[] = _C("%COMPUTERNAME%");
+clientchar_t VNLCComputerName[] = _C("%LCCOMPUTERNAME%");
typedef struct smb_findShare_rock {
- char * shareName;
- char * match;
+ clientchar_t * shareName;
+ clientchar_t * match;
int matchType;
} smb_findShare_rock_t;
{
int matchType = 0;
smb_findShare_rock_t * vrock = (smb_findShare_rock_t *) rockp;
- if (!strnicmp(dep->name, vrock->shareName, 12)) {
- if(!stricmp(dep->name, vrock->shareName))
+ normchar_t normName[MAX_PATH];
+
+ cm_FsStringToNormString(dep->name, -1, normName, sizeof(normName)/sizeof(normName[0]));
+
+ if (!cm_ClientStrCmpNI(normName, vrock->shareName, 12)) {
+ if(!cm_ClientStrCmpI(normName, vrock->shareName))
matchType = SMB_FINDSHARE_EXACT_MATCH;
else
matchType = SMB_FINDSHARE_PARTIAL_MATCH;
if(vrock->match) free(vrock->match);
- vrock->match = strdup(dep->name);
+ vrock->match = cm_FsStringToClientStringAlloc(dep->name, -1, NULL);
vrock->matchType = matchType;
if(matchType == SMB_FINDSHARE_EXACT_MATCH)
/* find a shareName in the table of submounts */
-int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp, char *shareName,
- char **pathNamep)
-{
- DWORD len;
- char pathName[1024];
- char *var;
- char temp[1024];
+int smb_FindShare(smb_vc_t *vcp, smb_user_t *uidp,
+ clientchar_t *shareName,
+ clientchar_t **pathNamep)
+{
+ DWORD cblen;
+ DWORD cchlen;
+ clientchar_t pathName[1024];
+ clientchar_t *var;
DWORD sizeTemp;
-#ifdef DJGPP
- char sbmtpath[MAX_PATH];
-#endif
- char *p, *q;
+ clientchar_t *p, *q;
+ fschar_t *cellname = NULL;
HKEY parmKey;
DWORD code;
DWORD allSubmount = 1;
* world to do so.
*/
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
- 0, KEY_QUERY_VALUE, &parmKey);
+ 0, KEY_QUERY_VALUE, &parmKey);
if (code == ERROR_SUCCESS) {
- len = sizeof(allSubmount);
+ cblen = sizeof(allSubmount);
code = RegQueryValueEx(parmKey, "AllSubmount", NULL, NULL,
- (BYTE *) &allSubmount, &len);
+ (BYTE *) &allSubmount, &cblen);
if (code != ERROR_SUCCESS) {
allSubmount = 1;
}
RegCloseKey (parmKey);
}
- if (allSubmount && _stricmp(shareName, "all") == 0) {
+ if (allSubmount && cm_ClientStrCmpI(shareName, _C("all")) == 0) {
*pathNamep = NULL;
return 1;
}
/* In case, the all share is disabled we need to still be able
* to handle ioctl requests
*/
- if (_stricmp(shareName, "ioctl$") == 0) {
- *pathNamep = strdup("/.__ioctl__");
+ if (cm_ClientStrCmpI(shareName, _C("ioctl$")) == 0) {
+ *pathNamep = cm_ClientStrDup(_C("/.__ioctl__"));
return 1;
}
- if (_stricmp(shareName, "IPC$") == 0 ||
- _stricmp(shareName, SMB_IOCTL_FILENAME_NOSLASH) == 0 ||
- _stricmp(shareName, "DESKTOP.INI") == 0
- ) {
+ if (cm_ClientStrCmpIA(shareName, _C("IPC$")) == 0 ||
+ cm_ClientStrCmpIA(shareName, _C("srvsvc")) == 0 ||
+ cm_ClientStrCmpIA(shareName, _C("wkssvc")) == 0 ||
+ cm_ClientStrCmpIA(shareName, _C(SMB_IOCTL_FILENAME_NOSLASH)) == 0 ||
+ cm_ClientStrCmpIA(shareName, _C("DESKTOP.INI")) == 0
+ ) {
*pathNamep = NULL;
return 0;
}
-#ifndef DJGPP
+ /* Check for volume references
+ *
+ * They look like <cell>{%,#}<volume>
+ */
+ if (cm_ClientStrChr(shareName, '%') != NULL ||
+ cm_ClientStrChr(shareName, '#') != NULL) {
+ clientchar_t 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_LogSaveClientString(smb_logp, shareName));
+
+ cm_ClientStrPrintfN(pathstr, lengthof(pathstr),
+ _C("/") _C(CM_PREFIX_VOL) _C("%s"), shareName);
+ cchlen = (DWORD)(cm_ClientStrLen(pathstr) + 1);
+
+ *pathNamep = malloc(cchlen * sizeof(clientchar_t));
+ if (*pathNamep) {
+ cm_ClientStrCpy(*pathNamep, cchlen, pathstr);
+ cm_ClientStrLwr(*pathNamep);
+ osi_Log1(smb_logp, " returning pathname [%S]",
+ osi_LogSaveClientString(smb_logp, *pathNamep));
+
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
- 0, KEY_QUERY_VALUE, &parmKey);
+ 0, KEY_QUERY_VALUE, &parmKey);
if (code == ERROR_SUCCESS) {
- len = sizeof(pathName);
- code = RegQueryValueEx(parmKey, shareName, NULL, NULL,
- (BYTE *) pathName, &len);
+ cblen = sizeof(pathName);
+ code = RegQueryValueExW(parmKey, shareName, NULL, NULL,
+ (BYTE *) pathName, &cblen);
if (code != ERROR_SUCCESS)
- len = 0;
+ cblen = 0;
RegCloseKey (parmKey);
} else {
- len = 0;
- }
-#else /* DJGPP */
- strcpy(sbmtpath, cm_confDir);
- strcat(sbmtpath, "/afsdsbmt.ini");
- len = GetPrivateProfileString("AFS Submounts", shareName, "",
- pathName, sizeof(pathName), sbmtpath);
-#endif /* !DJGPP */
- if (len != 0 && len != sizeof(pathName) - 1) {
+ cblen = 0;
+ }
+ cchlen = cblen / sizeof(clientchar_t);
+ if (cchlen != 0 && cchlen != lengthof(pathName) - 1) {
/* We can accept either unix or PC style AFS pathnames. Convert
* Unix-style to PC style here for internal use.
*/
p = pathName;
- if (strncmp(p, cm_mountRoot, strlen(cm_mountRoot)) == 0)
- p += strlen(cm_mountRoot); /* skip mount path */
+ cchlen = lengthof(pathName);
+
+ /* within this code block, we maintain, cchlen = writeable
+ buffer length of p */
+
+ if (cm_ClientStrCmpN(p, cm_mountRootC, cm_mountRootCLen) == 0) {
+ p += cm_mountRootCLen; /* skip mount path */
+ cchlen -= (p - pathName);
+ }
+
q = p;
while (*q) {
- if (*q == '/') *q = '\\'; /* change to \ */
+ if (*q == _C('/')) *q = _C('\\'); /* change to \ */
q++;
}
while (1)
{
+ clientchar_t temp[1024];
+
if (var = smb_stristr(p, VNUserName)) {
if (uidp && uidp->unp)
- smb_subst(p, var, sizeof(VNUserName),uidp->unp->name);
+ smb_subst(p, cchlen, var, lengthof(VNUserName),uidp->unp->name);
else
- smb_subst(p, var, sizeof(VNUserName)," ");
+ smb_subst(p, cchlen, var, lengthof(VNUserName), _C(" "));
}
else if (var = smb_stristr(p, VNLCUserName))
{
if (uidp && uidp->unp)
- strcpy(temp, uidp->unp->name);
+ cm_ClientStrCpy(temp, lengthof(temp), uidp->unp->name);
else
- strcpy(temp, " ");
- _strlwr(temp);
- smb_subst(p, var, sizeof(VNLCUserName), temp);
+ cm_ClientStrCpy(temp, lengthof(temp), _C(" "));
+ cm_ClientStrLwr(temp);
+ smb_subst(p, cchlen, var, lengthof(VNLCUserName), temp);
}
else if (var = smb_stristr(p, VNComputerName))
{
- sizeTemp = sizeof(temp);
- GetComputerName((LPTSTR)temp, &sizeTemp);
- smb_subst(p, var, sizeof(VNComputerName), temp);
+ sizeTemp = lengthof(temp);
+ GetComputerNameW(temp, &sizeTemp);
+ smb_subst(p, cchlen, var, lengthof(VNComputerName), temp);
}
else if (var = smb_stristr(p, VNLCComputerName))
{
- sizeTemp = sizeof(temp);
+ sizeTemp = lengthof(temp);
GetComputerName((LPTSTR)temp, &sizeTemp);
- _strlwr(temp);
- smb_subst(p, var, sizeof(VNLCComputerName), temp);
+ cm_ClientStrLwr(temp);
+ smb_subst(p, cchlen, var, lengthof(VNLCComputerName), temp);
}
else
break;
}
- *pathNamep = strdup(p);
+ *pathNamep = cm_ClientStrDup(p);
return 1;
}
else
cm_req_t req;
smb_findShare_rock_t vrock;
osi_hyper_t thyper;
- char * p = shareName;
+ fschar_t ftemp[1024];
+ clientchar_t * p = shareName;
int rw = 0;
/* attempt to locate a partial match in root.afs. This is because
thyper.HighPart = 0;
thyper.LowPart = 0;
- vrock.shareName = shareName;
+ vrock.shareName = cm_ClientStringToNormStringAlloc(shareName, -1, NULL);
vrock.match = NULL;
vrock.matchType = 0;
cm_HoldSCache(cm_data.rootSCachep);
code = cm_ApplyDir(cm_data.rootSCachep, smb_FindShareProc, &vrock, &thyper,
- (uidp? (uidp->unp ? uidp->unp->userp : NULL) : NULL), &req, NULL);
+ (uidp? (uidp->unp ? uidp->unp->userp : NULL) : NULL), &req, NULL);
cm_ReleaseSCache(cm_data.rootSCachep);
+ free(vrock.shareName);
+ vrock.shareName = NULL;
+
if (vrock.matchType) {
- sprintf(pathName,"/%s/",vrock.match);
- *pathNamep = strdup(strlwr(pathName));
+ cm_ClientStrPrintfN(pathName, lengthof(pathName), _C("/%s/"), vrock.match);
+ *pathNamep = cm_ClientStrDup(cm_ClientStrLwr(pathName));
free(vrock.match);
return 1;
}
rw = 1;
}
/* Get the full name for this cell */
- code = cm_SearchCellFile(p, temp, 0, 0);
+ cellname = cm_ClientStringToFsStringAlloc(p, cm_ClientStrLen(p), NULL);
+ code = cm_SearchCellFile(cellname, ftemp, 0, 0);
#ifdef AFS_AFSDB_ENV
if (code && cm_dnsEnabled) {
int ttl;
- code = cm_SearchCellByDNS(p, temp, &ttl, 0, 0);
+ code = cm_SearchCellByDNS(cellname, ftemp, &ttl, 0, 0);
}
#endif
+ if (cellname)
+ free(cellname);
+
/* construct the path */
- if (code == 0) {
- sprintf(pathName,rw ? "/.%s/" : "/%s/",temp);
- *pathNamep = strdup(strlwr(pathName));
+ if (code == 0) {
+ clientchar_t temp[1024];
+
+ cm_FsStringToClientString(ftemp, cm_FsStrLen(ftemp), temp, 1024);
+ cm_ClientStrPrintfN(pathName, lengthof(pathName),
+ rw ? _C("/.%S/") : _C("/%S/"), temp);
+ *pathNamep = cm_ClientStrDup(cm_ClientStrLwr(pathName));
return 1;
}
}
#define CSC_POLICY_PROGRAMS 2
#define CSC_POLICY_DISABLE 3
-int smb_FindShareCSCPolicy(char *shareName)
+int smb_FindShareCSCPolicy(clientchar_t *shareName)
{
DWORD len;
- char policy[1024];
+ clientchar_t policy[1024];
DWORD dwType;
HKEY hkCSCPolicy;
int retval = CSC_POLICY_MANUAL;
NULL );
len = sizeof(policy);
- if ( RegQueryValueEx( hkCSCPolicy, shareName, 0, &dwType, policy, &len ) ||
+ if ( RegQueryValueExW( hkCSCPolicy, shareName, 0, &dwType, (LPBYTE) policy, &len ) ||
len == 0) {
- retval = stricmp("all",shareName) ? CSC_POLICY_MANUAL : CSC_POLICY_DISABLE;
+ retval = cm_ClientStrCmpIA(_C("all"),shareName) ? CSC_POLICY_MANUAL : CSC_POLICY_DISABLE;
}
- else if (stricmp(policy, "documents") == 0)
+ else if (cm_ClientStrCmpIA(policy, _C("documents")) == 0)
{
retval = CSC_POLICY_DOCUMENTS;
}
- else if (stricmp(policy, "programs") == 0)
+ else if (cm_ClientStrCmpIA(policy, _C("programs")) == 0)
{
retval = CSC_POLICY_PROGRAMS;
}
- else if (stricmp(policy, "disable") == 0)
+ else if (cm_ClientStrCmpIA(policy, _C("disable")) == 0)
{
retval = CSC_POLICY_DISABLE;
}
{
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_ObtainWrite(&dsp->scp->rw);
if (dsp->flags & SMB_DIRSEARCH_BULKST) {
dsp->flags &= ~SMB_DIRSEARCH_BULKST;
dsp->scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
- dsp->scp->bulkStatProgress = hones;
+ dsp->scp->bulkStatProgress = hzero;
}
- lock_ReleaseMutex(&dsp->scp->mx);
+ lock_ReleaseWrite(&dsp->scp->rw);
}
lock_ReleaseMutex(&dsp->mx);
lock_ReleaseWrite(&smb_globalLock);
cm_scache_t *scp = NULL;
lock_ObtainMutex(&dsp->mx);
- osi_assert(dsp->refCount-- > 0);
+ osi_assertx(dsp->refCount-- > 0, "cm_scache_t refCount 0");
if (dsp->refCount == 0 && (dsp->flags & SMB_DIRSEARCH_DELETE)) {
if (&dsp->q == (osi_queue_t *) smb_lastDirSearchp)
smb_lastDirSearchp = (smb_dirSearch_t *) osi_QPrev(&smb_lastDirSearchp->q);
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;
static smb_packet_t *GetPacket(void)
{
smb_packet_t *tbp;
-#ifdef DJGPP
- unsigned int npar, seg, tb_sel;
-#endif
lock_ObtainWrite(&smb_globalLock);
tbp = smb_packetFreeListp;
smb_packetFreeListp = tbp->nextp;
lock_ReleaseWrite(&smb_globalLock);
if (!tbp) {
-#ifndef DJGPP
- tbp = calloc(65540,1);
-#else /* DJGPP */
- tbp = malloc(sizeof(smb_packet_t));
-#endif /* !DJGPP */
+ tbp = calloc(sizeof(*tbp),1);
tbp->magic = SMB_PACKETMAGIC;
tbp->ncbp = NULL;
tbp->vcp = NULL;
tbp->ncb_length = 0;
tbp->flags = 0;
tbp->spacep = NULL;
-
-#ifdef DJGPP
- npar = SMB_PACKETSIZE >> 4; /* number of paragraphs */
- {
- signed int retval =
- __dpmi_allocate_dos_memory(npar, &tb_sel); /* DOS segment */
- if (retval == -1) {
- osi_Log1(smb_logp, "Cannot allocate %d paragraphs of DOS memory",
- npar);
- osi_panic("",__FILE__,__LINE__);
- }
- else {
- osi_Log2(smb_logp, "Allocated %d paragraphs of DOS mem at 0x%X",
- npar, retval);
- seg = retval;
- }
- }
- tbp->dos_pkt = (seg * 16) + 0; /* DOS physical address */
- tbp->dos_pkt_sel = tb_sel;
-#endif /* DJGPP */
+ tbp->stringsp = NULL;
}
- osi_assert(tbp->magic == SMB_PACKETMAGIC);
+ osi_assertx(tbp->magic == SMB_PACKETMAGIC, "invalid smb_packet_t magic");
return tbp;
}
tbp = GetPacket();
memcpy(tbp, pkt, sizeof(smb_packet_t));
tbp->wctp = tbp->data + (unsigned int)(pkt->wctp - pkt->data);
+ tbp->stringsp = NULL;
if (tbp->vcp)
smb_HoldVC(tbp->vcp);
return tbp;
{
smb_ncb_t *tbp;
NCB *ncbp;
-#ifdef DJGPP
- unsigned int npar, seg, tb_sel;
-#endif /* DJGPP */
lock_ObtainWrite(&smb_globalLock);
tbp = smb_ncbFreeListp;
smb_ncbFreeListp = tbp->nextp;
lock_ReleaseWrite(&smb_globalLock);
if (!tbp) {
-#ifndef DJGPP
tbp = calloc(sizeof(*tbp),1);
-#else /* DJGPP */
- tbp = malloc(sizeof(*tbp));
- npar = (sizeof(NCB)+15) >> 4; /* number of paragraphs */
- {
- signed int retval =
- __dpmi_allocate_dos_memory(npar, &tb_sel); /* DOS segment */
- if (retval == -1) {
- osi_Log1(smb_logp, "Cannot allocate %d paragraphs of DOS mem in GetNCB",
- npar);
- osi_panic("",__FILE__,__LINE__);
- } else {
- osi_Log2(smb_logp, "Allocated %d paragraphs of DOS mem at 0x%X in GetNCB",
- npar, retval);
- seg = retval;
- }
- }
- tbp->dos_ncb = (seg * 16) + 0; /* DOS physical address */
- tbp->dos_ncb_sel = tb_sel;
-#endif /* !DJGPP */
tbp->magic = SMB_NCBMAGIC;
}
- osi_assert(tbp->magic == SMB_NCBMAGIC);
+ osi_assertx(tbp->magic == SMB_NCBMAGIC, "invalid smb_packet_t magic");
memset(&tbp->ncb, 0, sizeof(NCB));
ncbp = &tbp->ncb;
-#ifdef DJGPP
- dos_memset(tbp->dos_ncb, 0, sizeof(NCB));
-#endif /* DJGPP */
return ncbp;
}
+static void FreeSMBStrings(smb_packet_t * pkt)
+{
+ cm_space_t * s;
+ cm_space_t * ns;
+
+ for (s = pkt->stringsp; s; s = ns) {
+ ns = s->nextp;
+ cm_FreeSpace(s);
+ }
+ pkt->stringsp = NULL;
+}
+
void smb_FreePacket(smb_packet_t *tbp)
{
smb_vc_t * vcp = NULL;
- osi_assert(tbp->magic == SMB_PACKETMAGIC);
+ osi_assertx(tbp->magic == SMB_PACKETMAGIC, "invalid smb_packet_t magic");
lock_ObtainWrite(&smb_globalLock);
tbp->nextp = smb_packetFreeListp;
tbp->oddByte = 0;
tbp->ncb_length = 0;
tbp->flags = 0;
+ FreeSMBStrings(tbp);
lock_ReleaseWrite(&smb_globalLock);
if (vcp)
smb_ncb_t *tbp;
tbp = (smb_ncb_t *) bufferp;
- osi_assert(tbp->magic == SMB_NCBMAGIC);
+ osi_assertx(tbp->magic == SMB_NCBMAGIC, "invalid smb_packet_t magic");
lock_ObtainWrite(&smb_globalLock);
tbp->nextp = smb_ncbFreeListp;
}
/* 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;
parm, parmCount, smbp->ncb_length);
osi_Log3(smb_logp,"Bad SMB param %d out of %d, ncb len %d",
parm, parmCount, smbp->ncb_length);
-#ifndef DJGPP
LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM,
__FILE__, __LINE__, parm, parmCount, smbp->ncb_length);
-#endif /* !DJGPP */
osi_panic(s, __FILE__, __LINE__);
}
parmDatap = smbp->wctp + (2*parm) + 1;
}
/* 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;
+ unsigned char *parmDatap;
+
+ parmCount = *smbp->wctp;
+
+ if (parm + 1 >= 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] + (parmDatap[1] << 8) + (parmDatap[2] << 16) + (parmDatap[3] << 24);
+}
+
+/* return the parm'th parameter in the smbp packet */
unsigned int smb_GetSMBOffsetParm(smb_packet_t *smbp, int parm, int offset)
{
int parmCount;
sprintf(s, "Bad SMB param %d offset %d out of %d, ncb len %d",
parm, offset, parmCount, smbp->ncb_length);
-#ifndef DJGPP
LogEvent(EVENTLOG_ERROR_TYPE, MSG_BAD_SMB_PARAM_WITH_OFFSET,
__FILE__, __LINE__, parm, offset, parmCount, smbp->ncb_length);
-#endif /* !DJGPP */
osi_Log4(smb_logp, "Bad SMB param %d offset %d out of %d, ncb len %d",
parm, offset, parmCount, smbp->ncb_length);
osi_panic(s, __FILE__, __LINE__);
void smb_SetSMBParm(smb_packet_t *smbp, int slot, unsigned int parmValue)
{
- char *parmDatap;
+ unsigned char *parmDatap;
/* make sure we have enough slots */
if (*smbp->wctp <= slot)
void smb_SetSMBParmLong(smb_packet_t *smbp, int slot, unsigned int parmValue)
{
- char *parmDatap;
+ unsigned char *parmDatap;
/* make sure we have enough slots */
if (*smbp->wctp <= slot)
*parmDatap++ = parmValue & 0xff;
*parmDatap++ = (parmValue>>8) & 0xff;
*parmDatap++ = (parmValue>>16) & 0xff;
- *parmDatap++ = (parmValue>>24) & 0xff;
+ *parmDatap = (parmValue>>24) & 0xff;
}
void smb_SetSMBParmDouble(smb_packet_t *smbp, int slot, char *parmValuep)
{
- char *parmDatap;
+ unsigned char *parmDatap;
int i;
/* make sure we have enough slots */
void smb_SetSMBParmByte(smb_packet_t *smbp, int slot, unsigned int parmValue)
{
- char *parmDatap;
+ unsigned char *parmDatap;
/* make sure we have enough slots */
if (*smbp->wctp <= slot) {
*parmDatap++ = parmValue & 0xff;
}
-void smb_StripLastComponent(char *outPathp, char **lastComponentp, char *inPathp)
+
+
+void smb_StripLastComponent(clientchar_t *outPathp, clientchar_t **lastComponentp,
+ clientchar_t *inPathp)
{
- char *lastSlashp;
+ clientchar_t *lastSlashp;
- lastSlashp = strrchr(inPathp, '\\');
+ lastSlashp = cm_ClientStrRChr(inPathp, '\\');
if (lastComponentp)
*lastComponentp = lastSlashp;
if (lastSlashp) {
}
}
-unsigned char *smb_ParseASCIIBlock(unsigned char *inp, char **chainpp)
+clientchar_t *smb_ParseASCIIBlock(smb_packet_t * pktp, unsigned char *inp,
+ char **chainpp, int flags)
{
+ size_t cb;
+
if (*inp++ != 0x4)
return NULL;
- if (chainpp) {
- *chainpp = inp + strlen(inp) + 1; /* skip over null-terminated string */
+
+#ifdef SMB_UNICODE
+ if (!WANTS_UNICODE(pktp))
+ flags |= SMB_STRF_FORCEASCII;
+#endif
+
+ cb = sizeof(pktp->data) - (inp - pktp->data);
+ if (inp < pktp->data || inp >= pktp->data + sizeof(pktp->data)) {
+#ifdef DEBUG_UNICODE
+ DebugBreak();
+#endif
+ cb = sizeof(pktp->data);
+ }
+ return smb_ParseStringBuf(pktp->data, &pktp->stringsp, inp, &cb, chainpp, flags);
+}
+
+clientchar_t *smb_ParseString(smb_packet_t * pktp, unsigned char * inp,
+ char ** chainpp, int flags)
+{
+ size_t cb;
+
+#ifdef SMB_UNICODE
+ if (!WANTS_UNICODE(pktp))
+ flags |= SMB_STRF_FORCEASCII;
+#endif
+
+ cb = sizeof(pktp->data) - (inp - pktp->data);
+ if (inp < pktp->data || inp >= pktp->data + sizeof(pktp->data)) {
+#ifdef DEBUG_UNICODE
+ DebugBreak();
+#endif
+ cb = sizeof(pktp->data);
+ }
+ return smb_ParseStringBuf(pktp->data, &pktp->stringsp, inp, &cb, chainpp, flags);
+}
+
+clientchar_t *smb_ParseStringCb(smb_packet_t * pktp, unsigned char * inp,
+ size_t cb, char ** chainpp, int flags)
+{
+#ifdef SMB_UNICODE
+ if (!WANTS_UNICODE(pktp))
+ flags |= SMB_STRF_FORCEASCII;
+#endif
+
+ return smb_ParseStringBuf(pktp->data, &pktp->stringsp, inp, &cb, chainpp, flags);
+}
+
+clientchar_t *smb_ParseStringCch(smb_packet_t * pktp, unsigned char * inp,
+ size_t cch, char ** chainpp, int flags)
+{
+ size_t cb = cch;
+
+#ifdef SMB_UNICODE
+ if (!WANTS_UNICODE(pktp))
+ flags |= SMB_STRF_FORCEASCII;
+ else
+ cb = cch * sizeof(wchar_t);
+#endif
+
+ return smb_ParseStringBuf(pktp->data, &pktp->stringsp, inp, &cb, chainpp, flags);
+}
+
+clientchar_t *
+smb_ParseStringBuf(const char * bufbase,
+ cm_space_t ** stringspp,
+ unsigned char *inp, size_t *pcb_max,
+ char **chainpp, int flags)
+{
+#ifdef SMB_UNICODE
+ if (!(flags & SMB_STRF_FORCEASCII)) {
+ size_t cch_src;
+ cm_space_t * spacep;
+ int null_terms = 0;
+
+ if (bufbase && ((inp - bufbase) % 2) != 0) {
+ inp++; /* unicode strings are always word aligned */
+ }
+
+ if (*pcb_max > 0) {
+ if (FAILED(StringCchLengthW((const wchar_t *) inp, *pcb_max / sizeof(wchar_t),
+ &cch_src))) {
+ cch_src = *pcb_max / sizeof(wchar_t);
+ *pcb_max = 0;
+ null_terms = 0;
+ } else {
+ *pcb_max -= (cch_src + 1) * sizeof(wchar_t);
+ null_terms = 1;
+ }
+ } else {
+ cch_src = 0;
+ }
+
+ spacep = cm_GetSpace();
+ spacep->nextp = *stringspp;
+ *stringspp = spacep;
+
+ if (cch_src == 0) {
+ if (chainpp) {
+ *chainpp = inp + sizeof(wchar_t);
+ }
+
+ *(spacep->wdata) = 0;
+ return spacep->wdata;
+ }
+
+ StringCchCopyNW(spacep->wdata,
+ lengthof(spacep->wdata),
+ (const clientchar_t *) inp, cch_src);
+
+ if (chainpp)
+ *chainpp = inp + (cch_src + null_terms)*sizeof(wchar_t);
+
+ return spacep->wdata;
+
+ } else {
+#endif
+ cm_space_t * spacep;
+ int cchdest;
+
+ /* Not using Unicode */
+ if (chainpp) {
+ *chainpp = inp + strlen(inp) + 1;
+ }
+
+ spacep = cm_GetSpace();
+ spacep->nextp = *stringspp;
+ *stringspp = spacep;
+
+ cchdest = lengthof(spacep->wdata);
+ cm_Utf8ToUtf16(inp, *pcb_max, spacep->wdata, cchdest);
+
+ return spacep->wdata;
+#ifdef SMB_UNICODE
+ }
+#endif
+}
+
+unsigned char * smb_UnparseString(smb_packet_t * pktp, unsigned char * outp,
+ clientchar_t * str,
+ size_t * plen, int flags)
+{
+ size_t buffersize;
+ int align = 0;
+
+ if (outp == NULL) {
+ /* we are only calculating the required size */
+
+ if (plen == NULL)
+ return NULL;
+
+#ifdef SMB_UNICODE
+
+ if (WANTS_UNICODE(pktp) && !(flags & SMB_STRF_FORCEASCII)) {
+
+ StringCbLengthW(str, SMB_STRINGBUFSIZE * sizeof(wchar_t), plen);
+ if (!(flags & SMB_STRF_IGNORENULL))
+ *plen += sizeof(wchar_t);
+
+ return (unsigned char *) 1; /* return TRUE if we are using unicode */
+ }
+ else
+#endif
+ {
+ /* Storing ANSI */
+
+ int cch_str;
+ int cch_dest;
+
+ cch_str = cm_ClientStrLen(str);
+ cch_dest = cm_ClientStringToUtf8(str, cch_str, NULL, 0);
+
+ if (plen)
+ *plen = ((flags & SMB_STRF_IGNORENULL)? cch_dest: cch_dest+1);
+
+ return NULL;
+ }
+
+ /* Not reached. */
+ }
+
+ /* if outp != NULL ... */
+
+ /* Number of bytes left in the buffer.
+
+ If outp lies inside the packet data buffer, we assume that the
+ buffer is the packet data buffer. Otherwise we assume that the
+ buffer is sizeof(packet->data).
+
+ */
+ if (outp >= pktp->data && outp < pktp->data + sizeof(pktp->data)) {
+ align = ((outp - pktp->data) % 2);
+ buffersize = (pktp->data + sizeof(pktp->data)) - ((char *) outp);
+ } else {
+ align = (((size_t) outp) % 2);
+ buffersize = sizeof(pktp->data);
+ }
+
+#ifdef SMB_UNICODE
+
+ if (WANTS_UNICODE(pktp) && !(flags & SMB_STRF_FORCEASCII)) {
+ int nchars;
+
+ if (align)
+ *outp++ = '\0';
+
+ if (*str == _C('\0')) {
+
+ if (buffersize < sizeof(wchar_t))
+ return NULL;
+
+ *((wchar_t *) outp) = L'\0';
+ if (plen && !(flags & SMB_STRF_IGNORENULL))
+ *plen += sizeof(wchar_t);
+ return outp + sizeof(wchar_t);
+ }
+
+ nchars = cm_ClientStringToUtf16(str, -1, (wchar_t *) outp, buffersize / sizeof(wchar_t));
+ if (nchars == 0) {
+ osi_Log2(smb_logp, "UnparseString: Can't convert string to Unicode [%S], GLE=%d",
+ osi_LogSaveClientString(smb_logp, str),
+ GetLastError());
+ return NULL;
+ }
+
+ if (plen)
+ *plen += sizeof(wchar_t) * ((flags & SMB_STRF_IGNORENULL)? nchars - 1: nchars);
+
+ return outp + sizeof(wchar_t) * nchars;
+ }
+ else
+#endif
+ {
+ /* Storing ANSI */
+ size_t cch_dest;
+
+ cch_dest = cm_ClientStringToUtf8(str, -1, outp, buffersize);
+
+ if (plen)
+ *plen += ((flags & SMB_STRF_IGNORENULL)? cch_dest - 1: cch_dest);
+
+ return outp + cch_dest;
}
- return inp;
}
unsigned char *smb_ParseVblBlock(unsigned char *inp, char **chainpp, int *lengthp)
return inp;
}
+unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengthp)
+{
+ int tlen;
+
+ if (*inp++ != 0x1) return NULL;
+ tlen = inp[0] + (inp[1]<<8);
+ inp += 2; /* skip length field */
+
+ if (chainpp) {
+ *chainpp = inp + tlen;
+ }
+
+ if (lengthp) *lengthp = tlen;
+
+ return inp;
+}
+
/* format a packet as a response */
void smb_FormatResponsePacket(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *op)
{
outp->res[1] = inSmbp->res[1];
op->inCom = inSmbp->com;
}
- outp->reb = SMB_FLAGS_SERVER_TO_CLIENT | SMB_FLAGS_CANONICAL_PATHNAMES;
+ outp->reb = SMB_FLAGS_SERVER_TO_CLIENT;
+#ifdef SEND_CANONICAL_PATHNAMES
+ outp->reb |= SMB_FLAGS_CANONICAL_PATHNAMES;
+#endif
outp->flg2 = SMB_FLAGS2_KNOWS_LONG_NAMES;
+#ifdef SMB_UNICODE
+ if ((vcp->flags & SMB_VCFLAG_USEUNICODE) == SMB_VCFLAG_USEUNICODE)
+ outp->flg2 |= SMB_FLAGS2_UNICODE;
+#endif
/* copy fields in generic packet area */
op->wctp = &outp->wct;
long code = 0;
unsigned char *tp;
int localNCB = 0;
-#ifdef DJGPP
- dos_ptr dos_ncb;
-#endif /* DJGPP */
ncbp = inp->ncbp;
if (ncbp == NULL) {
ncbp = GetNCB();
localNCB = 1;
}
-#ifdef DJGPP
- dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
-#endif /* DJGPP */
memset((char *)ncbp, 0, sizeof(NCB));
ncbp->ncb_lsn = (unsigned char) vcp->lsn; /* vc to use */
ncbp->ncb_lana_num = vcp->lana;
ncbp->ncb_command = NCBSEND; /* op means send data */
-#ifndef DJGPP
ncbp->ncb_buffer = (char *) inp;/* packet */
code = Netbios(ncbp);
-#else /* DJGPP */
- ncbp->ncb_buffer = inp->dos_pkt;/* packet */
- ((smb_ncb_t*)ncbp)->orig_pkt = inp;
-
- /* copy header information from virtual to DOS address space */
- dosmemput((char*)inp, SMB_PACKETSIZE, inp->dos_pkt);
- code = Netbios(ncbp, dos_ncb);
-#endif /* !DJGPP */
if (code != 0) {
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 */
lock_ObtainMutex(&vcp->mx);
if (!(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
else if (code == CM_ERROR_READONLY) {
NTStatus = 0xC00000A2L; /* Write protected */
}
- else if (code == CM_ERROR_NOSUCHFILE) {
+ else if (code == CM_ERROR_NOSUCHFILE ||
+ code == CM_ERROR_BPLUS_NOMATCH) {
NTStatus = 0xC000000FL; /* No such file */
}
else if (code == CM_ERROR_NOSUCHPATH) {
NTStatus = 0xC09820FBL; /* SMB use standard */
}
else if (code == CM_ERROR_QUOTA) {
-#ifdef COMMENT
NTStatus = 0xC0000044L; /* Quota exceeded */
-#else
- NTStatus = 0xC000007FL; /* Disk full */
-#endif
}
else if (code == CM_ERROR_SPACE) {
NTStatus = 0xC000007FL; /* Disk full */
else if (code == CM_ERROR_PATH_NOT_COVERED) {
NTStatus = 0xC0000257L; /* Path Not Covered */
}
-#ifdef COMMENT
else if (code == CM_ERROR_ALLBUSY) {
- NTStatus = 0xC00000BFL; /* Network Busy */
+ NTStatus = 0xC000022DL; /* Retry */
}
else if (code == CM_ERROR_ALLOFFLINE || code == CM_ERROR_ALLDOWN) {
- NTStatus = 0xC0000350L; /* Remote Host Down */
- }
-#else
- /* we do not want to be telling the SMB/CIFS client that
- * the AFS Client Service is busy or down.
- */
- else if (code == CM_ERROR_ALLBUSY ||
- code == CM_ERROR_ALLOFFLINE ||
- code == CM_ERROR_ALLDOWN) {
NTStatus = 0xC00000BEL; /* Bad Network Path */
+ }
+ else if (code >= ERROR_TABLE_BASE_RXK && code < ERROR_TABLE_BASE_RXK + 256) {
+ NTStatus = 0xC0000322L; /* No Kerberos key */
+ }
+ else if (code == CM_ERROR_BAD_LEVEL) {
+ NTStatus = 0xC0000148L; /* Invalid Level */
+ }
+ else if (code == CM_ERROR_RANGE_NOT_LOCKED) {
+ NTStatus = 0xC000007EL; /* Range Not Locked */
+ }
+ else if (code == CM_ERROR_NOSUCHDEVICE) {
+ NTStatus = 0xC000000EL; /* No Such Device */
}
-#endif
- else if (code == RXKADUNKNOWNKEY) {
- NTStatus = 0xC0000322L; /* Bad Kerberos key */
+ else if (code == CM_ERROR_LOCK_NOT_GRANTED) {
+ NTStatus = 0xC0000055L; /* Lock Not Granted */
} else {
NTStatus = 0xC0982001L; /* SMB non-specific error */
}
class = 3;
error = 19; /* read only */
}
- else if (code == CM_ERROR_NOSUCHFILE) {
+ else if (code == CM_ERROR_NOSUCHFILE ||
+ code == CM_ERROR_BPLUS_NOMATCH) {
class = 1;
error = 2; /* ENOENT! */
}
return CM_ERROR_BADOP;
}
+/* SMB_COM_ECHO */
long smb_ReceiveCoreEcho(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned short EchoCount, i;
return 0;
}
+/* SMB_COM_READ_RAW */
long smb_ReceiveCoreReadRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
osi_hyper_t offset;
unsigned short fd;
unsigned pid;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp = NULL;
NCB *ncbp;
int rc;
-#ifndef DJGPP
char *rawBuf = NULL;
-#else
- dos_ptr rawBuf = NULL;
- dos_ptr dos_ncb;
-#endif /* DJGPP */
rawBuf = NULL;
finalCount = 0;
fd = smb_GetSMBParm(inp, 0);
count = smb_GetSMBParm(inp, 3);
minCount = smb_GetSMBParm(inp, 4);
- offset.HighPart = 0; /* too bad */
offset.LowPart = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16);
- osi_Log3(smb_logp, "smb_ReceieveCoreReadRaw fd %d, off 0x%x, size 0x%x",
- fd, offset.LowPart, count);
+ if (*inp->wctp == 10) {
+ /* we were sent a request with 64-bit file offsets */
+#ifdef AFS_LARGEFILES
+ offset.HighPart = smb_GetSMBParm(inp, 8) | (smb_GetSMBParm(inp, 9) << 16);
+
+ if (LargeIntegerLessThanZero(offset)) {
+ osi_Log0(smb_logp, "smb_ReceiveCoreReadRaw received negative 64-bit offset");
+ goto send1;
+ }
+#else
+ if ((smb_GetSMBParm(inp, 8) | (smb_GetSMBParm(inp, 9) << 16)) != 0) {
+ osi_Log0(smb_logp, "smb_ReceiveCoreReadRaw received 64-bit file offset. Dropping request.");
+ goto send1;
+ } else {
+ offset.HighPart = 0;
+ }
+#endif
+ } else {
+ /* we were sent a request with 32-bit file offsets */
+ offset.HighPart = 0;
+ }
+
+ osi_Log4(smb_logp, "smb_ReceieveCoreReadRaw fd %d, off 0x%x:%08x, size 0x%x",
+ fd, offset.HighPart, offset.LowPart, count);
fidp = smb_FindFID(vcp, fd, 0);
if (!fidp)
goto send1;
- pid = ((smb_t *) inp)->pid;
+ if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
+ smb_CloseFID(vcp, fidp, NULL, 0);
+ code = CM_ERROR_NOSUCHFILE;
+ goto send1a;
+ }
+
+
+ pid = smbp->pid;
{
LARGE_INTEGER LOffset, LLength;
cm_key_t key;
key = cm_GenerateKey(vcp->vcID, pid, fd);
- LOffset.HighPart = 0;
+ LOffset.HighPart = offset.HighPart;
LOffset.LowPart = offset.LowPart;
LLength.HighPart = 0;
LLength.LowPart = count;
- lock_ObtainMutex(&fidp->scp->mx);
+ lock_ObtainWrite(&fidp->scp->rw);
code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
- lock_ReleaseMutex(&fidp->scp->mx);
+ lock_ReleaseWrite(&fidp->scp->rw);
}
if (code) {
goto send1a;
if (smb_RawBufs) {
/* Get a raw buf, from head of list */
rawBuf = smb_RawBufs;
-#ifndef DJGPP
smb_RawBufs = *(char **)smb_RawBufs;
-#else /* DJGPP */
- smb_RawBufs = _farpeekl(_dos_ds, smb_RawBufs);
-#endif /* !DJGPP */
}
lock_ReleaseMutex(&smb_RawBufLock);
if (!rawBuf)
if (fidp->flags & SMB_FID_IOCTL)
{
lock_ReleaseMutex(&fidp->mx);
-#ifndef DJGPP
rc = smb_IoctlReadRaw(fidp, vcp, inp, outp);
-#else
- rc = smb_IoctlReadRaw(fidp, vcp, inp, outp, rawBuf);
-#endif
if (rawBuf) {
/* Give back raw buffer */
lock_ObtainMutex(&smb_RawBufLock);
-#ifndef DJGPP
*((char **) rawBuf) = smb_RawBufs;
-#else /* DJGPP */
- _farpokel(_dos_ds, rawBuf, smb_RawBufs);
-#endif /* !DJGPP */
smb_RawBufs = rawBuf;
lock_ReleaseMutex(&smb_RawBufLock);
}
+ lock_ReleaseMutex(&fidp->mx);
smb_ReleaseFID(fidp);
return rc;
}
userp = smb_GetUserFromVCP(vcp, inp);
-#ifndef DJGPP
code = smb_ReadData(fidp, &offset, count, rawBuf, userp, &finalCount);
-#else /* DJGPP */
- /* have to give ReadData flag so it will treat buffer as DOS mem. */
- code = smb_ReadData(fidp, &offset, count, (unsigned char *)rawBuf,
- userp, &finalCount, TRUE /* rawFlag */);
-#endif /* !DJGPP */
if (code != 0)
goto send;
send1:
ncbp = outp->ncbp;
-#ifdef DJGPP
- dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
-#endif /* DJGPP */
memset((char *)ncbp, 0, sizeof(NCB));
ncbp->ncb_length = (unsigned short) finalCount;
ncbp->ncb_command = NCBSEND;
ncbp->ncb_buffer = rawBuf;
-#ifndef DJGPP
code = Netbios(ncbp);
-#else /* DJGPP */
- code = Netbios(ncbp, dos_ncb);
-#endif /* !DJGPP */
if (code != 0)
osi_Log1(smb_logp, "ReadRaw send failure code %d", code);
if (rawBuf) {
/* Give back raw buffer */
lock_ObtainMutex(&smb_RawBufLock);
-#ifndef DJGPP
*((char **) rawBuf) = smb_RawBufs;
-#else /* DJGPP */
- _farpokel(_dos_ds, rawBuf, smb_RawBufs);
-#endif /* !DJGPP */
smb_RawBufs = rawBuf;
lock_ReleaseMutex(&smb_RawBufLock);
return 0;
}
+/* SMB_COM_NEGOTIATE */
long smb_ReceiveNegotiate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
char *namep;
int coreProtoIndex;
int v3ProtoIndex;
int NTProtoIndex;
+ int VistaProtoIndex;
int protoIndex; /* index we're using */
int namex;
int dbytes;
coreProtoIndex = -1; /* not found */
v3ProtoIndex = -1;
NTProtoIndex = -1;
+ VistaProtoIndex = -1;
while(namex < dbytes) {
osi_Log1(smb_logp, "Protocol %s",
osi_LogSaveString(smb_logp, namep+1));
else if (smb_useV3 && strcmp("NT LM 0.12", namep+1) == 0) {
NTProtoIndex = tcounter;
}
+ else if (smb_useV3 && strcmp("SMB 2.001", namep+1) == 0) {
+ VistaProtoIndex = tcounter;
+ }
/* compute size of protocol entry */
entryLength = (int)strlen(namep+1);
}
lock_ObtainMutex(&vcp->mx);
- if (NTProtoIndex != -1) {
+#if 0
+ if (VistaProtoIndex != -1) {
+ protoIndex = VistaProtoIndex;
+ vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3);
+ } else
+#endif
+ if (NTProtoIndex != -1) {
protoIndex = NTProtoIndex;
vcp->flags |= (SMB_VCFLAG_USENT | SMB_VCFLAG_USEV3);
}
if (protoIndex == -1)
return CM_ERROR_INVAL;
- else if (NTProtoIndex != -1) {
+ else if (VistaProtoIndex != 1 || NTProtoIndex != -1) {
smb_SetSMBParm(outp, 0, protoIndex);
if (smb_authType != SMB_AUTH_NONE) {
smb_SetSMBParmByte(outp, 1,
* and NT Find *
* and NT SMB's *
* and raw mode
- * and DFS */
+ * and DFS
+ * and Unicode */
caps = NTNEGOTIATE_CAPABILITY_NTSTATUS |
#ifdef DFS_SUPPORT
NTNEGOTIATE_CAPABILITY_DFS |
#endif
+#ifdef AFS_LARGEFILES
+ NTNEGOTIATE_CAPABILITY_LARGEFILES |
+#endif
NTNEGOTIATE_CAPABILITY_NTFIND |
NTNEGOTIATE_CAPABILITY_RAWMODE |
NTNEGOTIATE_CAPABILITY_NTSMB;
if ( smb_authType == SMB_AUTH_EXTENDED )
caps |= NTNEGOTIATE_CAPABILITY_EXTENDED_SECURITY;
+#ifdef SMB_UNICODE
+ if ( smb_UseUnicode ) {
+ caps |= NTNEGOTIATE_CAPABILITY_UNICODE;
+ }
+#endif
+
smb_SetSMBParmLong(outp, 9, caps);
time(&unixTime);
smb_SearchTimeFromUnixTime(&dosTime, unixTime);
datap = smb_GetSMBData(outp, NULL);
memcpy(datap,vcp->encKey,MSV1_0_CHALLENGE_LENGTH);
/* and the faux domain name */
- strcpy(datap + MSV1_0_CHALLENGE_LENGTH,smb_ServerDomainName);
+ cm_ClientStringToUtf8(smb_ServerDomainName, -1,
+ datap + MSV1_0_CHALLENGE_LENGTH,
+ sizeof(outp->data)/sizeof(char) - (datap - outp->data));
} else if ( smb_authType == SMB_AUTH_EXTENDED ) {
void * secBlob;
int secBlobLength;
/* paste in a new encryption key */
memcpy(datap, vcp->encKey, MSV1_0_CHALLENGE_LENGTH);
/* and the faux domain name */
- strcpy(datap + MSV1_0_CHALLENGE_LENGTH, smb_ServerDomainName);
+ cm_ClientStringToUtf8(smb_ServerDomainName, -1,
+ datap + MSV1_0_CHALLENGE_LENGTH,
+ sizeof(outp->data)/sizeof(char) - (datap - outp->data));
} else {
smb_SetSMBParm(outp, 11, 0); /* encryption key length */
smb_SetSMBParm(outp, 12, 0); /* resvd */
now = osi_Time();
lock_ObtainWrite(&smb_rctLock);
for ( unpp=&usernamesp; *unpp; ) {
- int delete = 0;
+ int deleteOk = 0;
smb_username_t *unp;
lock_ObtainMutex(&(*unpp)->mx);
;
else if (!smb_LogoffTokenTransfer ||
((*unpp)->last_logoff_t + smb_LogoffTransferTimeout < now))
- delete = 1;
+ deleteOk = 1;
lock_ReleaseMutex(&(*unpp)->mx);
- if (delete) {
+ if (deleteOk) {
cm_user_t * userp;
unp = *unpp;
free(unp->name);
free(unp->machine);
free(unp);
- if (userp) {
- lock_ReleaseWrite(&smb_rctLock);
+ if (userp)
cm_ReleaseUser(userp);
- lock_ObtainWrite(&smb_rctLock);
- }
} else {
unpp = &(*unpp)->nextp;
}
if (wl->state == SMB_WAITINGLOCKSTATE_DONE)
continue;
- osi_assert(wl->state != SMB_WAITINGLOCKSTATE_ERROR);
+ if (wl->state == SMB_WAITINGLOCKSTATE_CANCELLED) {
+ code = CM_ERROR_LOCK_NOT_GRANTED;
+ break;
+ }
+
+ osi_assertx(wl->state != SMB_WAITINGLOCKSTATE_ERROR, "!SMB_WAITINGLOCKSTATE_ERROR");
/* wl->state is either _DONE or _WAITING. _ERROR
would no longer be on the queue. */
if (code == CM_ERROR_WOULDBLOCK) {
/* no progress */
- if (wlRequest->timeRemaining != 0xffffffff
- && (wlRequest->timeRemaining -= 1000) < 0)
+ if (wlRequest->msTimeout != 0xffffffff
+ && ((osi_Time() - wlRequest->start_t) * 1000 > wlRequest->msTimeout))
goto endWait;
continue;
wlRequest);
scp = wlRequest->scp;
+ osi_Log2(smb_logp,"smb_WaitingLocksDaemon wlRequest 0x%p scp 0x%p", wlRequest, scp);
cm_InitReq(&req);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
for (wl = wlRequest->locks; wl; wl = wlNext) {
wlNext = (smb_waitingLock_t *) osi_QNext(&wl->q);
-
- cm_Unlock(scp, wlRequest->lockType, wl->LOffset,
- wl->LLength, wl->key, NULL, &req);
+
+ if (wl->state == SMB_WAITINGLOCKSTATE_DONE)
+ cm_Unlock(scp, wlRequest->lockType, wl->LOffset,
+ wl->LLength, wl->key, NULL, &req);
osi_QRemove((osi_queue_t **) &wlRequest->locks, &wl->q);
free(wl);
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
} else {
return 0;
}
+/* SMB_COM_TREE_CONNECT */
long smb_ReceiveCoreTreeConnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *rsp)
{
smb_tid_t *tidp;
smb_user_t *uidp;
unsigned short newTid;
- char shareName[256];
- char *sharePath;
+ clientchar_t shareName[AFSPATHMAX];
+ clientchar_t *sharePath;
int shareFound;
- char *tp;
- char *pathp;
- char *passwordp;
+ clientchar_t *tp;
+ clientchar_t *pathp;
cm_user_t *userp;
osi_Log0(smb_logp, "SMB receive tree connect");
/* parse input parameters */
- tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
- passwordp = smb_ParseASCIIBlock(tp, &tp);
- tp = strrchr(pathp, '\\');
+ {
+ char *tbp;
+ tbp = smb_GetSMBData(inp, NULL);
+ pathp = smb_ParseASCIIBlock(inp, tbp, &tbp, SMB_STRF_ANSIPATH);
+ }
+ tp = cm_ClientStrRChr(pathp, '\\');
if (!tp)
return CM_ERROR_BADSMB;
- strcpy(shareName, tp+1);
+ cm_ClientStrCpy(shareName, lengthof(shareName), tp+1);
lock_ObtainMutex(&vcp->mx);
newTid = vcp->tidCounter++;
if (uidp)
smb_ReleaseUID(uidp);
if (!shareFound) {
- smb_ReleaseTID(tidp);
+ smb_ReleaseTID(tidp, FALSE);
return CM_ERROR_BADSHARENAME;
}
lock_ObtainMutex(&tidp->mx);
tidp->userp = userp;
tidp->pathname = sharePath;
lock_ReleaseMutex(&tidp->mx);
- smb_ReleaseTID(tidp);
+ smb_ReleaseTID(tidp, FALSE);
smb_SetSMBParm(rsp, 0, SMB_PACKETSIZE);
smb_SetSMBParm(rsp, 1, newTid);
return 0;
}
-unsigned char *smb_ParseDataBlock(unsigned char *inp, char **chainpp, int *lengthp)
-{
- int tlen;
-
- if (*inp++ != 0x1) return NULL;
- tlen = inp[0] + (inp[1]<<8);
- inp += 2; /* skip length field */
-
- if (chainpp) {
- *chainpp = inp + tlen;
- }
-
- if (lengthp) *lengthp = tlen;
-
- return inp;
-}
-
/* set maskp to the mask part of the incoming path.
* Mask is 11 bytes long (8.3 with the dot elided).
* Returns true if succeeds with a valid name, otherwise it does
* its best, but returns false.
*/
-int smb_Get8Dot3MaskFromPath(unsigned char *maskp, unsigned char *pathp)
+int smb_Get8Dot3MaskFromPath(clientchar_t *maskp, clientchar_t *pathp)
{
- char *tp;
- char *up;
+ clientchar_t *tp;
+ clientchar_t *up;
int i;
int tc;
int valid8Dot3;
/* mask starts out all blanks */
memset(maskp, ' ', 11);
+ maskp[11] = '\0';
/* find last backslash, or use whole thing if there is none */
- tp = strrchr(pathp, '\\');
- if (!tp) tp = pathp;
- else tp++; /* skip slash */
+ tp = cm_ClientStrRChr(pathp, '\\');
+ if (!tp)
+ tp = pathp;
+ else
+ tp++; /* skip slash */
up = maskp;
/* names starting with a dot are illegal */
- if (*tp == '.') valid8Dot3 = 0;
+ if (*tp == '.')
+ valid8Dot3 = 0;
for(i=0;; i++) {
tc = *tp++;
- if (tc == 0) return valid8Dot3;
- if (tc == '.' || tc == '"') break;
- if (i < 8) *up++ = tc;
- else valid8Dot3 = 0;
+ if (tc == 0)
+ return valid8Dot3;
+ if (tc == '.' || tc == '"')
+ break;
+ if (i < 8)
+ *up++ = tc;
+ else
+ valid8Dot3 = 0;
}
/* if we get here, tp point after the dot */
/* unreachable */
}
-int smb_Match8Dot3Mask(char *unixNamep, char *maskp)
+int smb_Match8Dot3Mask(clientchar_t *unixNamep, clientchar_t *maskp)
{
- char umask[11];
+ clientchar_t umask[11];
int valid;
int i;
- char tc1;
- char tc2;
- char *tp1;
- char *tp2;
+ clientchar_t tc1;
+ clientchar_t tc2;
+ clientchar_t *tp1;
+ clientchar_t *tp2;
- /* XXX redo this, calling smb_V3MatchMask with a converted mask */
+ /* XXX redo this, calling cm_MatchMask with a converted mask */
valid = smb_Get8Dot3MaskFromPath(umask, unixNamep);
if (!valid)
tp1 = umask; /* real name, in mask format */
tp2 = maskp; /* mask, in mask format */
for(i=0; i<11; i++) {
- tc1 = *tp1++; /* char from real name */
- tc2 = *tp2++; /* char from mask */
- tc1 = (char) cm_foldUpper[(unsigned char)tc1];
- tc2 = (char) cm_foldUpper[(unsigned char)tc2];
+ tc1 = *tp1++; /* clientchar_t from real name */
+ tc2 = *tp2++; /* clientchar_t from mask */
+ tc1 = (clientchar_t) cm_foldUpper[(clientchar_t)tc1];
+ tc2 = (clientchar_t) cm_foldUpper[(clientchar_t)tc2];
if (tc1 == tc2)
continue;
if (tc2 == '?' && tc1 != ' ')
return 1;
}
-char *smb_FindMask(char *pathp)
+clientchar_t *smb_FindMask(clientchar_t *pathp)
{
- char *tp;
+ clientchar_t *tp;
- tp = strrchr(pathp, '\\'); /* find last slash */
+ tp = cm_ClientStrRChr(pathp, '\\'); /* find last slash */
if (tp)
return tp+1; /* skip the slash */
return pathp; /* no slash, return the entire path */
}
+/* SMB_COM_SEARCH for a volume label
+
+ (This is called from smb_ReceiveCoreSearchDir() and not an actual
+ dispatch function.) */
long smb_ReceiveCoreSearchVolume(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- unsigned char *pathp;
+ clientchar_t *pathp;
unsigned char *tp;
- unsigned char mask[11];
+ clientchar_t mask[12];
unsigned char *statBlockp;
unsigned char initStatBlock[21];
int statLen;
/* pull pathname and stat block out of request */
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, (char **) &tp);
- osi_assert(pathp != NULL);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
- statBlockp = smb_ParseVblBlock(tp, (char **) &tp, &statLen);
- osi_assert(statBlockp != NULL);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp,
+ SMB_STRF_ANSIPATH|SMB_STRF_FORCEASCII);
+ osi_assertx(pathp != NULL, "null path");
+ statBlockp = smb_ParseVblBlock(tp, &tp, &statLen);
+ osi_assertx(statBlockp != NULL, "null statBlock");
if (statLen == 0) {
statBlockp = initStatBlock;
statBlockp[0] = 8;
*tp++ = 0;
*tp++ = 0;
+ /* The filename is a UCHAR buffer that is ASCII even if Unicode
+ was negotiated. */
+
/* finally, null-terminated 8.3 pathname, which we set to AFS */
memset(tp, ' ', 13);
strcpy(tp, "AFS");
return 0;
}
-long smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
- cm_user_t *userp, cm_req_t *reqp)
+static long
+smb_ApplyDirListPatches(smb_dirListPatch_t **dirPatchespp,
+ clientchar_t * tidPathp, clientchar_t * relPathp,
+ cm_user_t *userp, cm_req_t *reqp)
{
long code = 0;
cm_scache_t *scp;
char attr;
smb_dirListPatch_t *patchp;
smb_dirListPatch_t *npatchp;
+ clientchar_t path[AFSPATHMAX];
for (patchp = *dirPatchespp; patchp; patchp =
(smb_dirListPatch_t *) osi_QNext(&patchp->q)) {
dptr = patchp->dptr;
+ cm_ClientStrPrintfN(path, AFSPATHMAX, _C("%s\\%s"),
+ relPathp ? relPathp : _C(""), patchp->dep->name);
+ reqp->relPathp = path;
+ reqp->tidPathp = tidPathp;
+
code = cm_GetSCache(&patchp->fid, &scp, userp, reqp);
+ reqp->relPathp = reqp->tidPathp = NULL;
+
if (code) {
if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE )
*dptr++ = SMB_ATTR_HIDDEN;
continue;
}
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, reqp, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE)
*dptr++ = SMB_ATTR_HIDDEN;
continue;
}
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+
+ lock_ConvertWToR(&scp->rw);
attr = smb_Attributes(scp);
/* check hidden attribute (the flag is only ON when dot file hiding is on ) */
if (patchp->flags & SMB_DIRLISTPATCH_DOTFILE)
/* copy out file length */
*((u_long *)dptr) = scp->length.LowPart;
dptr += 4;
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
cm_ReleaseSCache(scp);
}
return code;
}
+/* SMB_COM_SEARCH */
long smb_ReceiveCoreSearchDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
int attribute;
long nextCookie;
- char *tp;
+ unsigned char *tp;
long code = 0;
- char *pathp;
- cm_dirEntry_t *dep;
+ clientchar_t *pathp;
+ cm_dirEntry_t *dep = 0;
int maxCount;
smb_dirListPatch_t *dirListPatchesp;
smb_dirListPatch_t *curPatchp;
cm_pageHeader_t *pageHeaderp;
cm_user_t *userp = NULL;
int slotInPage;
- char shortName[13];
- char *actualName;
- char *shortNameEnd;
- char mask[11];
+ clientchar_t mask[12];
int returnedNames;
long nextEntryCookie;
int numDirChunks; /* # of 32 byte dir chunks in this entry */
int starPattern;
int rootPath = 0;
int caseFold;
- char *tidPathp;
+ clientchar_t *tidPathp = 0;
cm_req_t req;
cm_fid_t fid;
int fileType;
caseFold = CM_FLAG_CASEFOLD;
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp,
+ SMB_STRF_ANSIPATH|SMB_STRF_FORCEASCII);
inCookiep = smb_ParseVblBlock(tp, &tp, &dataLength);
/* bail out if request looks bad */
if (attribute & 0x8)
return smb_ReceiveCoreSearchVolume(vcp, inp, outp);
- osi_Log2(smb_logp, "SMB receive search dir count %d [%s]",
- maxCount, osi_LogSaveString(smb_logp, pathp));
+ osi_Log2(smb_logp, "SMB receive search dir count %d [%S]",
+ maxCount, osi_LogSaveClientString(smb_logp, pathp));
if (*pathp == 0) { /* null pathp, treat as root dir */
if (!(attribute & SMB_ATTR_DIRECTORY)) /* exclude dirs */
dsp = smb_NewDirSearch(0);
dsp->attribute = attribute;
smb_Get8Dot3MaskFromPath(mask, pathp);
- memcpy(dsp->mask, mask, 11);
+ memcpy(dsp->mask, mask, 12);
/* track if this is likely to match a lot of entries */
if (smb_IsStarMask(mask))
dsp = smb_FindDirSearch(inCookiep[12]);
if (!dsp) {
/* can't find dir search status; fatal error */
- osi_Log3(smb_logp, "SMB receive search dir bad cookie: cookie %d nextCookie %u [%s]",
- inCookiep[12], nextCookie, osi_LogSaveString(smb_logp, pathp));
+ osi_Log3(smb_logp, "SMB receive search dir bad cookie: cookie %d nextCookie %u [%S]",
+ inCookiep[12], nextCookie, osi_LogSaveClientString(smb_logp, pathp));
return CM_ERROR_BADFD;
}
attribute = dsp->attribute;
*/
memcpy(&clientCookie, &inCookiep[17], 4);
- memcpy(mask, dsp->mask, 11);
+ memcpy(mask, dsp->mask, 12);
/* assume we're doing a star match if it has continued for more
* than one call.
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 {
spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, NULL, pathp);
+ smb_StripLastComponent(spacep->wdata, NULL, pathp);
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
if (code) {
lock_ReleaseMutex(&dsp->mx);
smb_ReleaseDirSearch(dsp);
return CM_ERROR_NOFILES;
}
- code = cm_NameI(cm_data.rootSCachep, spacep->data,
+ cm_ClientStrCpy(dsp->tidPath, lengthof(dsp->tidPath), tidPathp ? tidPathp : _C("/"));
+ cm_ClientStrCpy(dsp->relPath, lengthof(dsp->relPath), spacep->wdata);
+
+ code = cm_NameI(cm_data.rootSCachep, spacep->wdata,
caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp);
if (code == 0) {
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc;
+
+ pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, spacep->wdata);
cm_ReleaseSCache(scp);
lock_ReleaseMutex(&dsp->mx);
cm_ReleaseUser(userp);
smb_DeleteDirSearch(dsp);
smb_ReleaseDirSearch(dsp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#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.
* now.
*/
cm_HoldSCache(scp);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0
&& LargeIntegerGreaterOrEqualToZero(scp->bulkStatProgress)) {
scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
dsp->flags |= SMB_DIRSEARCH_BULKST;
+ dsp->scp->bulkStatProgress = hzero;
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
}
}
lock_ReleaseMutex(&dsp->mx);
smb_SetSMBParm(outp, 0, 0);
/* get the directory size */
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) {
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
smb_DeleteDirSearch(dsp);
return code;
}
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+
dirLength = scp->length;
bufferp = NULL;
bufferOffset.LowPart = bufferOffset.HighPart = 0;
code = 0;
returnedNames = 0;
while (1) {
+ clientchar_t *actualName;
+ clientchar_t shortName[13];
+ clientchar_t *shortNameEnd;
+
/* make sure that curOffset.LowPart doesn't point to the first
* 32 bytes in the 2nd through last dir page, and that it doesn't
* point at the first 13 32-byte chunks in the first dir page,
buf_Release(bufferp);
bufferp = NULL;
}
- lock_ReleaseMutex(&scp->mx);
- lock_ObtainRead(&scp->bufCreateLock);
+ lock_ReleaseWrite(&scp->rw);
code = buf_Get(scp, &thyper, &bufferp);
- lock_ReleaseRead(&scp->bufCreateLock);
lock_ObtainMutex(&dsp->mx);
/* now, if we're doing a star match, do bulk fetching of all of
* the status info for files in the dir.
*/
if (starPattern) {
- smb_ApplyDirListPatches(&dirListPatchesp, userp, &req);
- lock_ObtainMutex(&scp->mx);
+ smb_ApplyDirListPatches(&dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
+ lock_ObtainWrite(&scp->rw);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper,
scp->bulkStatProgress)) {
/* Don't bulk stat if risking timeout */
int now = GetTickCount();
- if (now - req.startTime > 5000) {
+ if (now - req.startTime > RDRtimeout * 1000) {
scp->bulkStatProgress = thyper;
scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
dsp->flags &= ~SMB_DIRSEARCH_BULKST;
+ dsp->scp->bulkStatProgress = hzero;
} else
- cm_TryBulkStat(scp, &thyper, userp, &req);
+ code = cm_TryBulkStat(scp, &thyper, userp, &req);
}
} else {
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
}
lock_ReleaseMutex(&dsp->mx);
if (code) {
break;
}
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
+
if (cm_HaveBuffer(scp, bufferp, 0)) {
osi_Log2(smb_logp, "SMB search dir !HaveBuffer scp %x bufferp %x", scp, bufferp);
break;
nextEntryCookie = curOffset.LowPart + (CM_DIR_CHUNKSIZE * numDirChunks);
/* Compute 8.3 name if necessary */
- actualName = dep->name;
+ actualName = cm_FsStringToClientStringAlloc(dep->name, -1, NULL);
if (dep->fid.vnode != 0 && !cm_Is8Dot3(actualName)) {
- cm_Gen8Dot3Name(dep, shortName, &shortNameEnd);
+ free(actualName);
+ cm_Gen8Dot3NameInt(dep->name, &dep->fid, shortName, &shortNameEnd);
actualName = shortName;
}
- osi_Log3(smb_logp, "SMB search dir vn %d name %s (%s)",
- dep->fid.vnode, osi_LogSaveString(smb_logp, dep->name),
- osi_LogSaveString(smb_logp, actualName));
+ osi_Log3(smb_logp, "SMB search dir vn %d name %s (%S)",
+ dep->fid.vnode, osi_LogSaveString(smb_logp, dep->name),
+ osi_LogSaveClientString(smb_logp, actualName));
if (dep->fid.vnode != 0 && smb_Match8Dot3Mask(actualName, mask)) {
/* this is one of the entries to use: it is not deleted
if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */
{
/* We have already done the cm_TryBulkStat above */
- fid.cell = scp->fid.cell;
- fid.volume = scp->fid.volume;
- fid.vnode = ntohl(dep->fid.vnode);
- fid.unique = ntohl(dep->fid.unique);
+ cm_SetFid(&fid, scp->fid.cell, scp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique));
fileType = cm_FindFileType(&fid);
osi_Log2(smb_logp, "smb_ReceiveCoreSearchDir: file %s "
"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");
*op++ = resByte;
memcpy(op, mask, 11); op += 11;
- *op++ = (char) dsp->cookie; /* they say it must be non-zero */
- *op++ = (char)(nextEntryCookie & 0xff);
- *op++ = (char)((nextEntryCookie>>8) & 0xff);
- *op++ = (char)((nextEntryCookie>>16) & 0xff);
- *op++ = (char)((nextEntryCookie>>24) & 0xff);
+ *op++ = (unsigned char) dsp->cookie; /* they say it must be non-zero */
+ *op++ = (unsigned char)(nextEntryCookie & 0xff);
+ *op++ = (unsigned char)((nextEntryCookie>>8) & 0xff);
+ *op++ = (unsigned char)((nextEntryCookie>>16) & 0xff);
+ *op++ = (unsigned char)((nextEntryCookie>>24) & 0xff);
memcpy(op, &clientCookie, 4); op += 4;
/* now we emit the attribute. This is sort of tricky,
curPatchp = malloc(sizeof(*curPatchp));
osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q);
curPatchp->dptr = op;
- curPatchp->fid.cell = scp->fid.cell;
- curPatchp->fid.volume = scp->fid.volume;
- curPatchp->fid.vnode = ntohl(dep->fid.vnode);
- curPatchp->fid.unique = ntohl(dep->fid.unique);
+ cm_SetFid(&curPatchp->fid, scp->fid.cell, scp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique));
/* do hidden attribute here since name won't be around when applying
* dir list patches
* it fits in 8.3 or the pattern wouldn't match, but it
* never hurts to be sure.
*/
- strncpy(op, actualName, 13);
+ cm_ClientStringToUtf8(actualName, -1, op, 13);
if (smb_StoreAnsiFilenames)
CharToOem(op, op);
+ /* This is a UCHAR field, which is ASCII even if Unicode
+ is negotiated. */
/* Uppercase if requested by client */
if (!KNOWS_LONG_NAMES(inp))
} /* while copying data for dir listing */
/* release the mutex */
- lock_ReleaseMutex(&scp->mx);
- if (bufferp) buf_Release(bufferp);
+ lock_ReleaseWrite(&scp->rw);
+ if (bufferp) {
+ buf_Release(bufferp);
+ bufferp = NULL;
+ }
/* apply and free last set of patches; if not doing a star match, this
* will be empty, but better safe (and freeing everything) than sorry.
*/
- smb_ApplyDirListPatches(&dirListPatchesp, userp, &req);
+ smb_ApplyDirListPatches(&dirListPatchesp, dsp->tidPath, dsp->relPath, userp, &req);
/* special return code for unsuccessful search */
if (code == 0 && dataLength < 21 && returnedNames == 0)
* Deduct for them and fill in the length field.
*/
temp -= 3; /* deduct vbl block info */
- osi_assert(temp == (43 * returnedNames));
- origOp[1] = (char)(temp & 0xff);
- origOp[2] = (char)((temp>>8) & 0xff);
+ osi_assertx(temp == (43 * returnedNames), "unexpected data length");
+ origOp[1] = (unsigned char)(temp & 0xff);
+ origOp[2] = (unsigned char)((temp>>8) & 0xff);
if (returnedNames == 0)
smb_DeleteDirSearch(dsp);
smb_ReleaseDirSearch(dsp);
return code;
}
+
/* verify that this is a valid path to a directory. I don't know why they
* don't use the get file attributes call.
+ *
+ * SMB_COM_CHECK_DIRECTORY
*/
long smb_ReceiveCoreCheckPath(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- char *pathp;
+ clientchar_t *pathp;
long code = 0;
cm_scache_t *rootScp;
cm_scache_t *newScp;
cm_user_t *userp;
unsigned int attrs;
int caseFold;
- char *tidPathp;
+ clientchar_t *tidPathp;
cm_req_t req;
+ char * pdata;
cm_InitReq(&req);
- pathp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(pathp, NULL);
+ pdata = smb_GetSMBData(inp, NULL);
+ pathp = smb_ParseASCIIBlock(inp, pdata, NULL, SMB_STRF_ANSIPATH);
if (!pathp)
return CM_ERROR_BADFD;
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
- osi_Log1(smb_logp, "SMB receive check path %s",
- osi_LogSaveString(smb_logp, pathp));
+ osi_Log1(smb_logp, "SMB receive check path %S",
+ osi_LogSaveClientString(smb_logp, pathp));
rootScp = cm_data.rootSCachep;
#ifdef DFS_SUPPORT
if (newScp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newScp, tidPathp, pathp);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#endif /* DFS_SUPPORT */
/* now lock the vnode with a callback; returns with newScp locked */
- lock_ObtainMutex(&newScp->mx);
+ lock_ObtainWrite(&newScp->rw);
code = cm_SyncOp(newScp, NULL, userp, &req, PRSFS_LOOKUP,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
- if (code && code != CM_ERROR_NOACCESS) {
- lock_ReleaseMutex(&newScp->mx);
- cm_ReleaseSCache(newScp);
- cm_ReleaseUser(userp);
- return code;
+ if (code) {
+ if (code != CM_ERROR_NOACCESS) {
+ lock_ReleaseWrite(&newScp->rw);
+ cm_ReleaseSCache(newScp);
+ cm_ReleaseUser(userp);
+ return code;
+ }
+ } else {
+ cm_SyncOpDone(newScp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
}
attrs = smb_Attributes(newScp);
if (!(attrs & SMB_ATTR_DIRECTORY))
code = CM_ERROR_NOTDIR;
- lock_ReleaseMutex(&newScp->mx);
+ lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return code;
}
+/* SMB_COM_SET_INFORMATION */
long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- char *pathp;
+ clientchar_t *pathp;
long code = 0;
cm_scache_t *rootScp;
unsigned short attribute;
afs_uint32 dosTime;
cm_user_t *userp;
int caseFold;
- char *tidPathp;
+ clientchar_t *tidPathp;
+ char * datap;
cm_req_t req;
cm_InitReq(&req);
attribute = smb_GetSMBParm(inp, 0);
dosTime = smb_GetSMBParm(inp, 1) | (smb_GetSMBParm(inp, 2) << 16);
- pathp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(pathp, NULL);
+ datap = smb_GetSMBData(inp, NULL);
+ pathp = smb_ParseASCIIBlock(inp, datap, NULL, SMB_STRF_ANSIPATH);
if (!pathp)
return CM_ERROR_BADSMB;
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
osi_Log2(smb_logp, "SMB receive setfile attributes time %d, attr 0x%x",
dosTime, attribute);
cm_ReleaseUser(userp);
return code;
}
-
+
#ifdef DFS_SUPPORT
if (newScp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newScp, tidPathp, pathp);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
* need the current status to determine what the new status is, in some
* cases.
*/
- lock_ObtainMutex(&newScp->mx);
+ lock_ObtainWrite(&newScp->rw);
code = cm_SyncOp(newScp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
- lock_ReleaseMutex(&newScp->mx);
+ lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return code;
}
+ cm_SyncOpDone(newScp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+
/* Check for RO volume */
if (newScp->flags & CM_SCACHEFLAG_RO) {
- lock_ReleaseMutex(&newScp->mx);
+ lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return CM_ERROR_READONLY;
attr.mask |= CM_ATTRMASK_CLIENTMODTIME;
smb_UnixTimeFromDosUTime(&attr.clientModTime, dosTime);
}
- if ((newScp->unixModeBits & 0222) && (attribute & 1) != 0) {
+ if ((newScp->unixModeBits & 0222) && (attribute & SMB_ATTR_READONLY) != 0) {
/* we're told to make a writable file read-only */
attr.unixModeBits = newScp->unixModeBits & ~0222;
attr.mask |= CM_ATTRMASK_UNIXMODEBITS;
}
- else if ((newScp->unixModeBits & 0222) == 0 && (attribute & 1) == 0) {
+ else if ((newScp->unixModeBits & 0222) == 0 && (attribute & SMB_ATTR_READONLY) == 0) {
/* we're told to make a read-only file writable */
attr.unixModeBits = newScp->unixModeBits | 0222;
attr.mask |= CM_ATTRMASK_UNIXMODEBITS;
}
- lock_ReleaseMutex(&newScp->mx);
+ lock_ReleaseWrite(&newScp->rw);
/* now call setattr */
if (attr.mask)
return code;
}
+
long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- char *pathp;
+ clientchar_t *pathp;
long code = 0;
cm_scache_t *rootScp;
cm_scache_t *newScp, *dscp;
int attrs;
cm_user_t *userp;
int caseFold;
- char *tidPathp;
+ clientchar_t *tidPathp;
cm_space_t *spacep;
- char *lastComp;
+ clientchar_t *lastComp;
+ char * datap;
cm_req_t req;
cm_InitReq(&req);
- pathp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(pathp, NULL);
+ datap = smb_GetSMBData(inp, NULL);
+ pathp = smb_ParseASCIIBlock(inp, datap, NULL, SMB_STRF_ANSIPATH);
if (!pathp)
return CM_ERROR_BADSMB;
if (*pathp == 0) /* null path */
- pathp = "\\";
- else
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = _C("\\");
- osi_Log1(smb_logp, "SMB receive getfile attributes path %s",
- osi_LogSaveString(smb_logp, pathp));
+ osi_Log1(smb_logp, "SMB receive getfile attributes path %S",
+ osi_LogSaveClientString(smb_logp, pathp));
rootScp = cm_data.rootSCachep;
* http://msdn.microsoft.com/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_extending/custom.asp
*/
spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, &lastComp, pathp);
+ smb_StripLastComponent(spacep->wdata, &lastComp, pathp);
#ifndef SPECIAL_FOLDERS
- if (lastComp && stricmp(lastComp, "\\desktop.ini") == 0) {
- code = cm_NameI(rootScp, spacep->data,
+ if (lastComp && cm_ClientStrCmpIA(lastComp, _C("\\desktop.ini")) == 0) {
+ code = cm_NameI(rootScp, spacep->wdata,
caseFold | CM_FLAG_DIRSEARCH | CM_FLAG_FOLLOW,
userp, tidPathp, &req, &dscp);
if (code == 0) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
- if ( WANTS_DFS_PATHNAMES(inp) )
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp,
+ spacep->wdata);
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
code = CM_ERROR_NOSUCHFILE;
else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) {
cm_buf_t *bp = buf_Find(dscp, &hzero);
- if (bp)
+ if (bp) {
buf_Release(bp);
- else
+ bp = NULL;
+ } else
code = CM_ERROR_NOSUCHFILE;
}
cm_ReleaseSCache(dscp);
#ifdef DFS_SUPPORT
if (newScp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newScp, tidPathp, pathp);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
#endif /* DFS_SUPPORT */
/* now lock the vnode with a callback; returns with newScp locked */
- lock_ObtainMutex(&newScp->mx);
+ lock_ObtainWrite(&newScp->rw);
code = cm_SyncOp(newScp, NULL, userp, &req, 0,
CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK);
if (code) {
- lock_ReleaseMutex(&newScp->mx);
+ lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return code;
}
+ cm_SyncOpDone(newScp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
+
#ifdef undef
/* use smb_Attributes instead. Also the fact that a file is
* in a readonly volume doesn't mean it shojuld be marked as RO
*/
if (newScp->fileType == CM_SCACHETYPE_DIRECTORY ||
- newScp->fileType == CM_SCACHETYPE_MOUNTPOINT)
+ newScp->fileType == CM_SCACHETYPE_MOUNTPOINT ||
+ newScp->fileType == CM_SCACHETYPE_INVALID)
attrs = SMB_ATTR_DIRECTORY;
else
attrs = 0;
smb_SetSMBParm(outp, 8, 0);
smb_SetSMBParm(outp, 9, 0);
smb_SetSMBDataLength(outp, 0);
- lock_ReleaseMutex(&newScp->mx);
+ lock_ReleaseWrite(&newScp->rw);
cm_ReleaseSCache(newScp);
cm_ReleaseUser(userp);
return 0;
}
+/* SMB_COM_TREE_DISCONNECT */
long smb_ReceiveCoreTreeDisconnect(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_tid_t *tidp;
tidp = smb_FindTID(vcp, ((smb_t *)inp)->tid, 0);
if (tidp) {
lock_ObtainWrite(&smb_rctLock);
- tidp->delete = 1;
+ tidp->deleteOk = 1;
+ smb_ReleaseTID(tidp, TRUE);
lock_ReleaseWrite(&smb_rctLock);
- smb_ReleaseTID(tidp);
}
return 0;
}
+/* SMB_COM_0PEN */
long smb_ReceiveCoreOpen(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
smb_fid_t *fidp;
- char *pathp;
- char *lastNamep;
+ clientchar_t *pathp;
+ clientchar_t *lastNamep;
int share;
int attribute;
long code = 0;
afs_uint32 dosTime;
int caseFold;
cm_space_t *spacep;
- char *tidPathp;
+ clientchar_t *tidPathp;
+ char * datap;
cm_req_t req;
cm_InitReq(&req);
- pathp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(pathp, NULL);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
-
- osi_Log1(smb_logp, "SMB receive open file [%s]", osi_LogSaveString(smb_logp, pathp));
+ datap = smb_GetSMBData(inp, NULL);
+ pathp = smb_ParseASCIIBlock(inp, datap, NULL, SMB_STRF_ANSIPATH);
+
+ osi_Log1(smb_logp, "SMB receive open file [%S]", osi_LogSaveClientString(smb_logp, pathp));
#ifdef DEBUG_VERBOSE
{
attribute = smb_GetSMBParm(inp, 1);
spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, &lastNamep, pathp);
- if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) {
+ smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
+ if (lastNamep && cm_ClientStrCmp(lastNamep, _C(SMB_IOCTL_FILENAME)) == 0) {
/* special case magic file name for receiving IOCTL requests
* (since IOCTL calls themselves aren't getting through).
*/
#ifdef DFS_SUPPORT
if (scp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(scp, tidPathp, pathp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
}
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
- osi_assert(fidp);
+ osi_assertx(fidp, "null smb_fid_t");
/* save a pointer to the vnode */
fidp->scp = scp;
+ osi_Log2(smb_logp,"smb_ReceiveCoreOpen fidp 0x%p scp 0x%p", fidp, scp);
+ lock_ObtainWrite(&scp->rw);
+ scp->flags |= CM_SCACHEFLAG_SMB_FID;
+ lock_ReleaseWrite(&scp->rw);
+
/* 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);
+ lock_ObtainRead(&scp->rw);
smb_SetSMBParm(outp, 0, fidp->fid);
smb_SetSMBParm(outp, 1, smb_Attributes(scp));
smb_DosUTimeFromUnixTime(&dosTime, scp->clientModTime);
/* pass the open mode back; XXXX add access checks */
smb_SetSMBParm(outp, 6, (share & 0xf));
smb_SetSMBDataLength(outp, 0);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseRead(&scp->rw);
/* notify open */
cm_Open(scp, 0, userp);
cm_user_t *userp;
cm_req_t *reqp;
smb_vc_t *vcp;
- char *maskp; /* pointer to the star pattern */
+ clientchar_t *maskp; /* pointer to the star pattern */
int flags;
int any;
+ cm_dirEntryList_t * matches;
} smb_unlinkRock_t;
int smb_UnlinkProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
smb_unlinkRock_t *rockp;
int caseFold;
int match;
- char shortName[13];
- char *matchName;
+ normchar_t matchName[MAX_PATH];
rockp = vrockp;
if (!(rockp->vcp->flags & SMB_VCFLAG_USEV3))
caseFold |= CM_FLAG_8DOT3;
- matchName = dep->name;
- match = smb_V3MatchMask(matchName, rockp->maskp, caseFold);
+ cm_FsStringToNormString(dep->name, -1, matchName, lengthof(matchName));
+ match = cm_MatchMask(matchName, rockp->maskp, caseFold);
if (!match &&
- (rockp->flags & SMB_MASKFLAG_TILDE) &&
- !cm_Is8Dot3(dep->name)) {
- cm_Gen8Dot3Name(dep, shortName, NULL);
- matchName = shortName;
+ (rockp->flags & SMB_MASKFLAG_TILDE) &&
+ !cm_Is8Dot3(matchName)) {
+ cm_Gen8Dot3Name(dep, matchName, NULL);
/* 8.3 matches are always case insensitive */
- match = smb_V3MatchMask(matchName, rockp->maskp, caseFold | CM_FLAG_CASEFOLD);
+ match = cm_MatchMask(matchName, rockp->maskp, caseFold | CM_FLAG_CASEFOLD);
}
if (match) {
- osi_Log1(smb_logp, "Unlinking %s",
- osi_LogSaveString(smb_logp, matchName));
- code = cm_Unlink(dscp, dep->name, rockp->userp, rockp->reqp);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_REMOVED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- dscp, dep->name, NULL, TRUE);
- if (code == 0) {
- rockp->any = 1;
+ osi_Log1(smb_logp, "Found match %S",
+ osi_LogSaveClientString(smb_logp, matchName));
- /* If we made a case sensitive exact match, we might as well quit now. */
- if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !strcmp(matchName, rockp->maskp))
- code = CM_ERROR_STOPNOW;
- }
+ cm_DirEntryListAdd(dep->name, &rockp->matches);
+
+ rockp->any = 1;
+
+ /* If we made a case sensitive exact match, we might as well quit now. */
+ if (!(rockp->flags & SMB_MASKFLAG_CASEFOLD) && !cm_ClientStrCmp(matchName, rockp->maskp))
+ code = CM_ERROR_STOPNOW;
+ else
+ code = 0;
}
else code = 0;
return code;
}
+/* SMB_COM_DELETE */
long smb_ReceiveCoreUnlink(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
int attribute;
long code = 0;
- char *pathp;
- char *tp;
+ clientchar_t *pathp;
+ unsigned char *tp;
cm_space_t *spacep;
cm_scache_t *dscp;
- char *lastNamep;
+ clientchar_t *lastNamep;
smb_unlinkRock_t rock;
cm_user_t *userp;
osi_hyper_t thyper;
int caseFold;
- char *tidPathp;
+ clientchar_t *tidPathp;
cm_req_t req;
cm_InitReq(&req);
attribute = smb_GetSMBParm(inp, 0);
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
- osi_Log1(smb_logp, "SMB receive unlink %s",
- osi_LogSaveString(smb_logp, pathp));
+ osi_Log1(smb_logp, "SMB receive unlink %S",
+ osi_LogSaveClientString(smb_logp, pathp));
spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, &lastNamep, pathp);
+ smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
userp = smb_GetUserFromVCP(vcp, inp);
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
- code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold, userp, tidPathp,
+ code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold, userp, tidPathp,
&req, &dscp);
if (code) {
cm_ReleaseUser(userp);
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
lastNamep++;
rock.any = 0;
- rock.maskp = smb_FindMask(pathp);
- rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0);
+ rock.maskp = cm_ClientStringToNormStringAlloc(smb_FindMask(pathp), -1, NULL);
+ rock.flags = ((cm_ClientStrChr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0);
thyper.LowPart = 0;
thyper.HighPart = 0;
rock.reqp = &req;
rock.dscp = dscp;
rock.vcp = vcp;
+ rock.matches = NULL;
/* Now, if we aren't dealing with a wildcard match, we first try an exact
* match. If that fails, we do a case insensitve match.
if (code == CM_ERROR_STOPNOW)
code = 0;
+ if (code == 0 && rock.matches) {
+ cm_dirEntryList_t * entry;
+
+ for (entry = rock.matches; code == 0 && entry; entry = entry->nextp) {
+ normchar_t normalizedName[MAX_PATH];
+
+ /* Note: entry->name is a non-normalized name */
+
+ osi_Log1(smb_logp, "Unlinking %s",
+ osi_LogSaveString(smb_logp, entry->name));
+
+ cm_FsStringToNormString(entry->name, -1,
+ normalizedName, lengthof(normalizedName));
+
+ code = cm_Unlink(dscp, entry->name, normalizedName, userp, &req);
+
+ if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
+ smb_NotifyChange(FILE_ACTION_REMOVED,
+ FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION,
+ dscp, normalizedName, NULL, TRUE);
+ }
+ }
+
+ cm_DirEntryListFree(&rock.matches);
+
cm_ReleaseUser(userp);
cm_ReleaseSCache(dscp);
+ free(rock.maskp);
+
if (code == 0 && !rock.any)
code = CM_ERROR_NOSUCHFILE;
return code;
}
typedef struct smb_renameRock {
- cm_scache_t *odscp; /* old dir */
- cm_scache_t *ndscp; /* new dir */
- cm_user_t *userp; /* user */
- cm_req_t *reqp; /* request struct */
- smb_vc_t *vcp; /* virtual circuit */
- char *maskp; /* pointer to star pattern of old file name */
- int flags; /* tilde, casefold, etc */
- char *newNamep; /* ptr to the new file's name */
+ cm_scache_t *odscp; /* old dir */
+ cm_scache_t *ndscp; /* new dir */
+ cm_user_t *userp; /* user */
+ cm_req_t *reqp; /* request struct */
+ smb_vc_t *vcp; /* virtual circuit */
+ normchar_t *maskp; /* pointer to star pattern of old file name */
+ int flags; /* tilde, casefold, etc */
+ clientchar_t *newNamep; /* ptr to the new file's name */
+ fschar_t fsOldName[MAX_PATH]; /* raw FS name */
+ clientchar_t clOldName[MAX_PATH]; /* client 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];
+ normchar_t matchName[MAX_PATH];
rockp = (smb_renameRock_t *) vrockp;
+ cm_FsStringToNormString(dep->name, -1, matchName, lengthof(matchName));
caseFold = ((rockp->flags & SMB_MASKFLAG_CASEFOLD)? CM_FLAG_CASEFOLD : 0);
if (!(rockp->vcp->flags & SMB_VCFLAG_USEV3))
caseFold |= CM_FLAG_8DOT3;
- match = smb_V3MatchMask(dep->name, rockp->maskp, caseFold);
+ match = cm_MatchMask(matchName, rockp->maskp, caseFold);
if (!match &&
(rockp->flags & SMB_MASKFLAG_TILDE) &&
- !cm_Is8Dot3(dep->name)) {
- cm_Gen8Dot3Name(dep, shortName, NULL);
- match = smb_V3MatchMask(shortName, rockp->maskp, caseFold);
+ !cm_Is8Dot3(matchName)) {
+ cm_Gen8Dot3Name(dep, matchName, NULL);
+ match = cm_MatchMask(matchName, rockp->maskp, caseFold);
}
+
if (match) {
- 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.
- */
- if (code == 0)
- code = CM_ERROR_STOPNOW;
- }
- else code = 0;
+ rockp->any = 1;
+ StringCbCopyA(rockp->fsOldName, sizeof(rockp->fsOldName), dep->name);
+ cm_ClientStrCpy(rockp->clOldName, lengthof(rockp->clOldName),
+ matchName);
+ code = CM_ERROR_STOPNOW;
+ } else {
+ code = 0;
+ }
return code;
}
long
-smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp, int attrs)
+smb_Rename(smb_vc_t *vcp, smb_packet_t *inp, clientchar_t * oldPathp, clientchar_t * newPathp, int attrs)
{
long code = 0;
cm_space_t *spacep = NULL;
cm_scache_t *newDscp = NULL;
cm_scache_t *tmpscp= NULL;
cm_scache_t *tmpscp2 = NULL;
- char *oldLastNamep;
- char *newLastNamep;
+ clientchar_t *oldLastNamep;
+ clientchar_t *newLastNamep;
osi_hyper_t thyper;
cm_user_t *userp;
int caseFold;
- char *tidPathp;
+ clientchar_t *tidPathp;
DWORD filter;
cm_req_t req;
cm_InitReq(&req);
spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp);
+ smb_StripLastComponent(spacep->wdata, &oldLastNamep, oldPathp);
caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD;
- code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold,
+ code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold,
userp, tidPathp, &req, &oldDscp);
if (code) {
cm_ReleaseUser(userp);
#ifdef DFS_SUPPORT
if (oldDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->wdata);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
}
#endif /* DFS_SUPPORT */
- smb_StripLastComponent(spacep->data, &newLastNamep, newPathp);
- code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold,
+ smb_StripLastComponent(spacep->wdata, &newLastNamep, newPathp);
+ code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold,
userp, tidPathp, &req, &newDscp);
if (code) {
#ifdef DFS_SUPPORT
if (newDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newDscp, tidPathp, spacep->wdata);
cm_ReleaseSCache(oldDscp);
cm_ReleaseSCache(newDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
rock.userp = userp;
rock.reqp = &req;
rock.vcp = vcp;
- rock.maskp = oldLastNamep;
- rock.flags = ((strchr(oldLastNamep, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0);
+ rock.maskp = cm_ClientStringToNormStringAlloc(oldLastNamep, -1, NULL);
+ rock.flags = ((cm_ClientStrChr(oldLastNamep, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0);
rock.newNamep = newLastNamep;
+ rock.fsOldName[0] = '\0';
+ rock.clOldName[0] = '\0';
+ 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));
+ if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_BPLUS_NOMATCH) &&
+ (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) )
+ {
+ osi_Log2(smb_logp, " lookup returns %ld for [%S]", code,
+ osi_LogSaveClientString(smb_logp, newLastNamep));
/* Check if the old and the new names differ only in case. If so return
* success, else return CM_ERROR_EXISTS
*/
- if (!code && oldDscp == newDscp && !stricmp(oldLastNamep, newLastNamep)) {
+ if (!code && oldDscp == newDscp && !cm_ClientStrCmpI(oldLastNamep, newLastNamep)) {
/* This would be a success only if the old file is *as same as* the new file */
code = cm_Lookup(oldDscp, oldLastNamep, CM_FLAG_CHECKPATH, userp, &req, &tmpscp2);
cm_ReleaseSCache(newDscp);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
+
+ free(rock.maskp);
+ rock.maskp = NULL;
return code;
}
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 = 0;
- else if (code == 0)
+ if (code == CM_ERROR_STOPNOW && rock.fsOldName[0] != '\0') {
+ code = cm_Rename(rock.odscp, rock.fsOldName, rock.clOldName,
+ rock.ndscp, rock.newNamep, rock.userp,
+ rock.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);
+ } else if (code == 0) {
code = CM_ERROR_NOSUCHFILE;
+ }
/* Handle Change Notification */
/*
* Being lazy, not distinguishing between files and dirs in this
* filter, since we'd have to do a lookup.
*/
- filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME;
- if (oldDscp == newDscp) {
- if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH)
- smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME,
- filter, oldDscp, oldLastNamep,
- newLastNamep, TRUE);
- } else {
- if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH)
- smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME,
- filter, oldDscp, oldLastNamep,
- NULL, TRUE);
- if (newDscp->flags & CM_SCACHEFLAG_ANYWATCH)
- smb_NotifyChange(FILE_ACTION_RENAMED_NEW_NAME,
- filter, newDscp, newLastNamep,
- NULL, TRUE);
+ if (code == 0) {
+ filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME;
+ if (oldDscp == newDscp) {
+ if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME,
+ filter, oldDscp, rock.clOldName,
+ newLastNamep, TRUE);
+ } else {
+ if (oldDscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_RENAMED_OLD_NAME,
+ filter, oldDscp, rock.clOldName,
+ NULL, TRUE);
+ if (newDscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_RENAMED_NEW_NAME,
+ filter, newDscp, newLastNamep,
+ NULL, TRUE);
+ }
}
if (tmpscp != NULL)
cm_ReleaseUser(userp);
cm_ReleaseSCache(oldDscp);
cm_ReleaseSCache(newDscp);
+
+ free(rock.maskp);
+ rock.maskp = NULL;
+
return code;
}
long
-smb_Link(smb_vc_t *vcp, smb_packet_t *inp, char * oldPathp, char * newPathp)
+smb_Link(smb_vc_t *vcp, smb_packet_t *inp, clientchar_t * oldPathp, clientchar_t * newPathp)
{
long code = 0;
cm_space_t *spacep = NULL;
cm_scache_t *tmpscp= NULL;
cm_scache_t *tmpscp2 = NULL;
cm_scache_t *sscp = NULL;
- char *oldLastNamep;
- char *newLastNamep;
+ clientchar_t *oldLastNamep;
+ clientchar_t *newLastNamep;
cm_user_t *userp;
int caseFold;
- char *tidPathp;
+ clientchar_t *tidPathp;
DWORD filter;
cm_req_t req;
caseFold = CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD;
spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, &oldLastNamep, oldPathp);
+ smb_StripLastComponent(spacep->wdata, &oldLastNamep, oldPathp);
- code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold,
+ code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold,
userp, tidPathp, &req, &oldDscp);
if (code) {
cm_ReleaseUser(userp);
#ifdef DFS_SUPPORT
if (oldDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(oldDscp, tidPathp, spacep->wdata);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
}
#endif /* DFS_SUPPORT */
- smb_StripLastComponent(spacep->data, &newLastNamep, newPathp);
- code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold,
+ smb_StripLastComponent(spacep->wdata, &newLastNamep, newPathp);
+ code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold,
userp, tidPathp, &req, &newDscp);
if (code) {
cm_ReleaseSCache(oldDscp);
#ifdef DFS_SUPPORT
if (newDscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(newDscp, tidPathp, spacep->wdata);
cm_ReleaseSCache(newDscp);
cm_ReleaseSCache(oldDscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
newLastNamep++;
/* now lookup the old name */
- osi_Log1(smb_logp," looking up [%s]", osi_LogSaveString(smb_logp,oldLastNamep));
+ osi_Log1(smb_logp," looking up [%S]", osi_LogSaveClientString(smb_logp,oldLastNamep));
code = cm_Lookup(oldDscp, oldLastNamep, CM_FLAG_CHECKPATH | CM_FLAG_CASEFOLD, userp, &req, &sscp);
if (code) {
cm_ReleaseSCache(oldDscp);
/* 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));
+ if ((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_BPLUS_NOMATCH) &&
+ (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) )
+ {
+ osi_Log2(smb_logp, " lookup returns %ld for [%S]", code,
+ osi_LogSaveClientString(smb_logp, newLastNamep));
/* if the existing link is to the same file, then we return success */
if (!code) {
}
/* now create the hardlink */
- osi_Log1(smb_logp," Attempting to create new link [%s]", osi_LogSaveString(smb_logp, newLastNamep));
+ osi_Log1(smb_logp," Attempting to create new link [%S]", osi_LogSaveClientString(smb_logp, newLastNamep));
code = cm_Link(newDscp, newLastNamep, sscp, 0, userp, &req);
osi_Log1(smb_logp," Link returns 0x%x", code);
return code;
}
+/* SMB_COM_RENAME */
long
smb_ReceiveCoreRename(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- char *oldPathp;
- char *newPathp;
- char *tp;
+ clientchar_t *oldPathp;
+ clientchar_t *newPathp;
+ unsigned char *tp;
+ long code;
tp = smb_GetSMBData(inp, NULL);
- oldPathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(oldPathp,oldPathp);
- newPathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(newPathp,newPathp);
-
- osi_Log2(smb_logp, "smb rename [%s] to [%s]",
- osi_LogSaveString(smb_logp, oldPathp),
- osi_LogSaveString(smb_logp, newPathp));
-
- return smb_Rename(vcp,inp,oldPathp,newPathp,0);
+ oldPathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
+ newPathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
+
+ osi_Log2(smb_logp, "smb rename [%S] to [%S]",
+ osi_LogSaveClientString(smb_logp, oldPathp),
+ osi_LogSaveClientString(smb_logp, newPathp));
+
+ code = smb_Rename(vcp,inp,oldPathp,newPathp,0);
+
+ osi_Log1(smb_logp, "smb rename returns 0x%x", code);
+ return code;
}
cm_scache_t *dscp;
cm_user_t *userp;
cm_req_t *reqp;
- char *maskp; /* pointer to the star pattern */
+ normchar_t *maskp; /* pointer to the star pattern */
int flags;
int any;
+ cm_dirEntryList_t * matches;
} smb_rmdirRock_t;
int smb_RmdirProc(cm_scache_t *dscp, cm_dirEntry_t *dep, void *vrockp, osi_hyper_t *offp)
long code = 0;
smb_rmdirRock_t *rockp;
int match;
- char shortName[13];
- char *matchName;
+ normchar_t matchName[MAX_PATH];
rockp = (smb_rmdirRock_t *) vrockp;
- matchName = dep->name;
+ cm_FsStringToNormString(dep->name, -1, matchName, lengthof(matchName));
if (rockp->flags & SMB_MASKFLAG_CASEFOLD)
- match = (cm_stricmp(matchName, rockp->maskp) == 0);
+ match = (cm_ClientStrCmpI(matchName, rockp->maskp) == 0);
else
- match = (strcmp(matchName, rockp->maskp) == 0);
+ match = (cm_ClientStrCmp(matchName, rockp->maskp) == 0);
if (!match &&
(rockp->flags & SMB_MASKFLAG_TILDE) &&
- !cm_Is8Dot3(dep->name)) {
- cm_Gen8Dot3Name(dep, shortName, NULL);
- matchName = shortName;
- match = (cm_stricmp(matchName, rockp->maskp) == 0);
+ !cm_Is8Dot3(matchName)) {
+ cm_Gen8Dot3Name(dep, matchName, NULL);
+ match = (cm_ClientStrCmpI(matchName, rockp->maskp) == 0);
}
+
if (match) {
- osi_Log1(smb_logp, "Removing directory %s",
- osi_LogSaveString(smb_logp, matchName));
- code = cm_RemoveDir(dscp, dep->name, rockp->userp, rockp->reqp);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_REMOVED,
- FILE_NOTIFY_CHANGE_DIR_NAME,
- dscp, dep->name, NULL, TRUE);
- if (code == 0)
- rockp->any = 1;
+ rockp->any = 1;
+ cm_DirEntryListAdd(dep->name, &rockp->matches);
}
- else code = 0;
- return code;
+ return 0;
}
+
long smb_ReceiveCoreRemoveDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
long code = 0;
- char *pathp;
- char *tp;
+ clientchar_t *pathp;
+ unsigned char *tp;
cm_space_t *spacep;
cm_scache_t *dscp;
- char *lastNamep;
+ clientchar_t *lastNamep;
smb_rmdirRock_t rock;
cm_user_t *userp;
osi_hyper_t thyper;
int caseFold;
- char *tidPathp;
+ clientchar_t *tidPathp;
cm_req_t req;
cm_InitReq(&req);
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, &lastNamep, pathp);
+ smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
userp = smb_GetUserFromVCP(vcp, inp);
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
- code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW,
+ code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold | CM_FLAG_FOLLOW,
userp, tidPathp, &req, &dscp);
if (code) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
lastNamep++;
rock.any = 0;
- rock.maskp = lastNamep;
- rock.flags = ((strchr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0);
+ rock.maskp = cm_ClientStringToNormStringAlloc(lastNamep, -1, NULL);
+ rock.flags = ((cm_ClientStrChr(rock.maskp, '~') != NULL) ? SMB_MASKFLAG_TILDE : 0);
thyper.LowPart = 0;
thyper.HighPart = 0;
rock.userp = userp;
rock.reqp = &req;
rock.dscp = dscp;
+ rock.matches = NULL;
+
/* 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) {
code = cm_ApplyDir(dscp, smb_RmdirProc, &rock, &thyper, userp, &req, NULL);
}
+ if (code == 0 && rock.matches) {
+ cm_dirEntryList_t * entry;
+
+ for (entry = rock.matches; code == 0 && entry; entry = entry->nextp) {
+ clientchar_t clientName[MAX_PATH];
+
+ cm_FsStringToClientString(entry->name, -1, clientName, lengthof(clientName));
+
+ osi_Log1(smb_logp, "Removing directory %s",
+ osi_LogSaveString(smb_logp, entry->name));
+
+ code = cm_RemoveDir(dscp, entry->name, clientName, userp, &req);
+
+ if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
+ smb_NotifyChange(FILE_ACTION_REMOVED,
+ FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION,
+ dscp, clientName, NULL, TRUE);
+ }
+ }
+
+ cm_DirEntryListFree(&rock.matches);
+
cm_ReleaseUser(userp);
cm_ReleaseSCache(dscp);
if (code == 0 && !rock.any)
code = CM_ERROR_NOSUCHFILE;
+
+ free(rock.maskp);
+ rock.maskp = NULL;
+
return code;
}
+/* SMB_COM_FLUSH */
long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned short fid;
if (!fidp)
return CM_ERROR_BADFD;
+ if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
+ smb_CloseFID(vcp, fidp, NULL, 0);
+ smb_ReleaseFID(fidp);
+ return CM_ERROR_NOSUCHFILE;
+ }
+
lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL) {
lock_ReleaseMutex(&fidp->mx);
userp = smb_GetUserFromVCP(vcp, inp);
lock_ObtainMutex(&fidp->mx);
- if (fidp->flags & SMB_FID_OPENWRITE) {
+ if ((fidp->flags & SMB_FID_OPENWRITE) && smb_AsyncStore != 2) {
cm_scache_t * scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
}
struct smb_FullNameRock {
- char *name;
- cm_scache_t *vnode;
- char *fullName;
+ clientchar_t *name;
+ cm_scache_t *vnode;
+ clientchar_t *fullName;
+ fschar_t *originalName;
};
int smb_FullNameProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp,
osi_hyper_t *offp)
{
- char shortName[13];
+ normchar_t matchName[MAX_PATH];
struct smb_FullNameRock *vrockp;
vrockp = (struct smb_FullNameRock *)rockp;
- if (!cm_Is8Dot3(dep->name)) {
+ cm_FsStringToNormString(dep->name, -1, matchName, lengthof(matchName));
+
+ if (!cm_Is8Dot3(matchName)) {
+ clientchar_t shortName[13];
+
cm_Gen8Dot3Name(dep, shortName, NULL);
- if (cm_stricmp(shortName, vrockp->name) == 0) {
- vrockp->fullName = strdup(dep->name);
+ if (cm_ClientStrCmpIA(shortName, vrockp->name) == 0) {
+ vrockp->fullName = cm_ClientStrDup(matchName);
+ vrockp->originalName = cm_FsStrDup(dep->name);
return CM_ERROR_STOPNOW;
}
}
- if (cm_stricmp(dep->name, vrockp->name) == 0 &&
+ if (cm_ClientStrCmpI(matchName, vrockp->name) == 0 &&
ntohl(dep->fid.vnode) == vrockp->vnode->fid.vnode &&
ntohl(dep->fid.unique) == vrockp->vnode->fid.unique) {
- vrockp->fullName = strdup(dep->name);
+ vrockp->fullName = cm_ClientStrDup(matchName);
+ vrockp->originalName = cm_FsStrDup(dep->name);
return CM_ERROR_STOPNOW;
}
return 0;
}
-void smb_FullName(cm_scache_t *dscp, cm_scache_t *scp, char *pathp,
- char **newPathp, cm_user_t *userp, cm_req_t *reqp)
+void smb_FullName(cm_scache_t *dscp, cm_scache_t *scp, clientchar_t *pathp,
+ clientchar_t **newPathp, fschar_t ** originalPathp,
+ cm_user_t *userp, cm_req_t *reqp)
{
struct smb_FullNameRock rock;
long code = 0;
+ memset(&rock, 0, sizeof(rock));
rock.name = pathp;
rock.vnode = scp;
code = cm_ApplyDir(dscp, smb_FullNameProc, &rock, NULL, userp, reqp, NULL);
- if (code == CM_ERROR_STOPNOW)
+ if (code == CM_ERROR_STOPNOW) {
*newPathp = rock.fullName;
- else
- *newPathp = strdup(pathp);
+ *originalPathp = rock.originalName;
+ } else {
+ *newPathp = cm_ClientStrDup(pathp);
+ *originalPathp = cm_ClientStringToFsStringAlloc(pathp, -1, NULL);
+ }
}
long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
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;
+ cm_scache_t *dscp = NULL;
+ clientchar_t *pathp = NULL;
+ cm_scache_t * scp = NULL;
+ cm_scache_t *delscp = NULL;
+ 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);
cm_InitReq(&req);
lock_ObtainWrite(&smb_rctLock);
- if (fidp->delete) {
+ if (fidp->deleteOk) {
osi_Log0(smb_logp, " Fid already closed.");
lock_ReleaseWrite(&smb_rctLock);
return CM_ERROR_BADFD;
}
- fidp->delete = 1;
+ fidp->deleteOk = 1;
lock_ReleaseWrite(&smb_rctLock);
lock_ObtainMutex(&fidp->mx);
+ if (fidp->NTopen_dscp) {
+ dscp = fidp->NTopen_dscp;
+ cm_HoldSCache(dscp);
+ }
+
+ if (fidp->NTopen_pathp) {
+ pathp = cm_ClientStrDup(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);
lock_ObtainMutex(&fidp->mx);
}
- scp = fidp->scp;
- if (scp)
- cm_HoldSCache(scp);
-
/* watch for ioctl closes, and read-only opens */
if (scp != NULL &&
(fidp->flags & (SMB_FID_OPENWRITE | SMB_FID_DELONCLOSE))
CompensateForSmbClientLastWriteTimeBugs(&dosTime);
smb_UnixTimeFromDosUTime(&fidp->scp->clientModTime, dosTime);
}
- lock_ReleaseMutex(&fidp->mx);
- code = cm_FSync(scp, userp, &req);
- lock_ObtainMutex(&fidp->mx);
+ if (smb_AsyncStore != 2) {
+ lock_ReleaseMutex(&fidp->mx);
+ code = cm_FSync(scp, userp, &req);
+ lock_ObtainMutex(&fidp->mx);
+ }
}
else
code = 0;
/* CM_UNLOCK_BY_FID doesn't look at the process ID. We pass
in zero. */
key = cm_GenerateKey(vcp->vcID, 0, fidp->fid);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
tcode = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
cm_UnlockByKey(scp, key, CM_UNLOCK_BY_FID, userp, &req);
- cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_LOCK);
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_LOCK);
post_syncopdone:
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&fidp->mx);
}
if (fidp->flags & SMB_FID_DELONCLOSE) {
- char *fullPathp;
+ clientchar_t *fullPathp = NULL;
+ fschar_t *originalNamep = NULL;
lock_ReleaseMutex(&fidp->mx);
- smb_FullName(dscp, scp, pathp, &fullPathp, userp, &req);
- if (scp->fileType == CM_SCACHETYPE_DIRECTORY) {
- code = cm_RemoveDir(dscp, fullPathp, userp, &req);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_REMOVED,
- FILE_NOTIFY_CHANGE_DIR_NAME,
- dscp, fullPathp, NULL, TRUE);
+
+ code = cm_Lookup(dscp, pathp, CM_FLAG_NOMOUNTCHASE, userp, &req, &delscp);
+ if (code) {
+ cm_HoldSCache(scp);
+ delscp = scp;
+ }
+ smb_FullName(dscp, delscp, pathp, &fullPathp, &originalNamep, userp, &req);
+ if (delscp->fileType == CM_SCACHETYPE_DIRECTORY) {
+ code = cm_RemoveDir(dscp, originalNamep, fullPathp, userp, &req);
+ if (code == 0) {
+ if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_REMOVED,
+ FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_CREATION,
+ dscp, fullPathp, NULL, TRUE);
+ }
} else {
- code = cm_Unlink(dscp, fullPathp, userp, &req);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_REMOVED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
- dscp, fullPathp, NULL, TRUE);
+ code = cm_Unlink(dscp, originalNamep, fullPathp, userp, &req);
+ if (code == 0) {
+ if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
+ smb_NotifyChange(FILE_ACTION_REMOVED,
+ FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION,
+ dscp, fullPathp, NULL, TRUE);
+ }
}
- free(fullPathp);
+
+ if (fullPathp)
+ free(fullPathp);
+ if (originalNamep)
+ free(originalNamep);
+
lock_ObtainMutex(&fidp->mx);
fidp->flags &= ~SMB_FID_DELONCLOSE;
}
/* if this was a newly created file, then clear the creator
* in the stat cache entry. */
if (fidp->flags & SMB_FID_CREATED) {
- lock_ObtainMutex(&scp->mx);
- if (scp->creator == userp)
- scp->creator = NULL;
- lock_ReleaseMutex(&scp->mx);
+ nullcreator = 1;
fidp->flags &= ~SMB_FID_CREATED;
}
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_assertx(fidp->NTopen_dscp == NULL, "null NTopen_dsc");
+ osi_assertx(fidp->NTopen_pathp == NULL, "null NTopen_path");
}
+
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;
}
lock_ReleaseMutex(&fidp->mx);
if (dscp)
cm_ReleaseSCache(dscp);
- if (scp)
+ if (delscp) {
+ cm_ReleaseSCache(delscp);
+ }
+
+ if (scp) {
+ lock_ObtainWrite(&scp->rw);
+ if (nullcreator && scp->creator == userp)
+ scp->creator = NULL;
+ scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
+ lock_ReleaseWrite(&scp->rw);
cm_ReleaseSCache(scp);
+ }
if (pathp)
free(pathp);
return code;
}
+/* SMB_COM_CLOSE */
long smb_ReceiveCoreClose(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
unsigned short fid;
/*
* smb_ReadData -- common code for Read, Read And X, and Raw Read
*/
-#ifndef DJGPP
-long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
+long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char *op,
cm_user_t *userp, long *readp)
-#else /* DJGPP */
-long smb_ReadData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
- cm_user_t *userp, long *readp, int dosflag)
-#endif /* !DJGPP */
{
osi_hyper_t offset;
long code = 0;
osi_hyper_t thyper;
osi_hyper_t lastByte;
osi_hyper_t bufferOffset;
- long bufIndex, nbytes;
+ long bufIndex;
+ afs_uint32 nbytes;
int chunk;
- int sequential = 0;
+ int sequential = (fidp->flags & SMB_FID_SEQUENTIAL);
cm_req_t req;
+ osi_Log3(smb_logp, "smb_ReadData fid %d, off 0x%x, size 0x%x",
+ fidp->fid, offsetp->LowPart, count);
+
+ *readp = 0;
+
+ lock_ObtainMutex(&fidp->mx);
+ /* make sure we have a readable FD */
+ if (!(fidp->flags & SMB_FID_OPENREAD_LISTDIR)) {
+ osi_Log2(smb_logp, "smb_ReadData fid %d not OPENREAD_LISTDIR flags 0x%x",
+ fidp->fid, fidp->flags);
+ lock_ReleaseMutex(&fidp->mx);
+ code = CM_ERROR_BADFDOP;
+ goto done2;
+ }
+
cm_InitReq(&req);
bufferp = NULL;
offset = *offsetp;
- lock_ObtainMutex(&fidp->mx);
scp = fidp->scp;
- lock_ObtainMutex(&scp->mx);
+ cm_HoldSCache(scp);
+ lock_ObtainWrite(&scp->rw);
if (offset.HighPart == 0) {
chunk = offset.LowPart >> cm_logChunkSize;
fidp->prev_chunk = fidp->curr_chunk;
fidp->curr_chunk = chunk;
}
- if (fidp->curr_chunk == fidp->prev_chunk + 1)
+ if (!(fidp->flags & SMB_FID_RANDOM) && (fidp->curr_chunk == fidp->prev_chunk + 1))
sequential = 1;
}
lock_ReleaseMutex(&fidp->mx);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
- if (code) goto done;
+ if (code)
+ goto done;
+
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
/* now we have the entry locked, look up the length */
fileLength = scp->length;
buf_Release(bufferp);
bufferp = NULL;
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
- lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &thyper, &bufferp);
- lock_ReleaseRead(&scp->bufCreateLock);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if (code) goto done;
bufferOffset = thyper;
code = cm_SyncOp(scp, bufferp, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK |
CM_SCACHESYNC_READ);
- if (code) goto done;
-
+ if (code)
+ goto done;
+
+ cm_SyncOpDone(scp, bufferp, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_READ);
+
if (cm_HaveBuffer(scp, bufferp, 0)) break;
/* otherwise, load the buffer and try again */
if (nbytes > count) nbytes = count; /* don't go past EOF */
/* now copy the data */
-#ifdef DJGPP
- if (dosflag)
- dosmemput(bufferp->datap + bufIndex, nbytes, (dos_ptr)op);
- else
-#endif /* DJGPP */
- memcpy(op, bufferp->datap + bufIndex, nbytes);
+ memcpy(op, bufferp->datap + bufIndex, nbytes);
/* adjust counters, pointers, etc. */
op += nbytes;
} /* while 1 */
done:
- lock_ReleaseMutex(&scp->mx);
- if (bufferp)
+ lock_ReleaseWrite(&scp->rw);
+ if (bufferp)
buf_Release(bufferp);
if (code == 0 && sequential)
- cm_ConsiderPrefetch(scp, &lastByte, userp, &req);
+ cm_ConsiderPrefetch(scp, &lastByte, *readp, userp, &req);
+ cm_ReleaseSCache(scp);
+
+ done2:
+ osi_Log3(smb_logp, "smb_ReadData fid %d returns 0x%x read %d bytes",
+ fidp->fid, code, *readp);
return code;
}
/*
* smb_WriteData -- common code for Write and Raw Write
*/
-#ifndef DJGPP
-long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
+long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, afs_uint32 count, char *op,
cm_user_t *userp, long *writtenp)
-#else /* DJGPP */
-long smb_WriteData(smb_fid_t *fidp, osi_hyper_t *offsetp, long count, char *op,
- cm_user_t *userp, long *writtenp, int dosflag)
-#endif /* !DJGPP */
{
- osi_hyper_t offset;
+ osi_hyper_t offset = *offsetp;
long code = 0;
long written = 0;
- cm_scache_t *scp;
+ cm_scache_t *scp = NULL;
osi_hyper_t fileLength; /* file's length at start of write */
osi_hyper_t minLength; /* don't read past this */
- long nbytes; /* # of bytes to transfer this iteration */
- cm_buf_t *bufferp;
+ afs_uint32 nbytes; /* # of bytes to transfer this iteration */
+ cm_buf_t *bufferp = NULL;
osi_hyper_t thyper; /* hyper tmp variable */
osi_hyper_t bufferOffset;
- long bufIndex; /* index in buffer where our data is */
- int doWriteBack;
- osi_hyper_t writeBackOffset;/* offset of region to write back when
- * I/O is done */
+ afs_uint32 bufIndex; /* index in buffer where our data is */
+ int doWriteBack = 0;
+ osi_hyper_t writeBackOffset;/* offset of region to write back when I/O is done */
DWORD filter = 0;
cm_req_t req;
*writtenp = 0;
- cm_InitReq(&req);
-
- bufferp = NULL;
- doWriteBack = 0;
- offset = *offsetp;
-
lock_ObtainMutex(&fidp->mx);
/* make sure we have a writable FD */
if (!(fidp->flags & SMB_FID_OPENWRITE)) {
fidp->fid, fidp->flags);
lock_ReleaseMutex(&fidp->mx);
code = CM_ERROR_BADFDOP;
- goto done;
+ goto done2;
}
+ cm_InitReq(&req);
+
scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
if (code)
goto done;
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_SETSTATUS | CM_SCACHESYNC_GETSTATUS);
+
/* now we have the entry locked, look up the length */
fileLength = scp->length;
minLength = fileLength;
/* now, if the new position (thyper) and the old (offset) are in
* different storeback windows, remember to store back the previous
* storeback window when we're done with the write.
+ *
+ * the purpose of this logic is to slow down the CIFS client
+ * in order to avoid the client disconnecting during the CLOSE
+ * operation if there are too many dirty buffers left to write
+ * than can be accomplished during 45 seconds. This used to be
+ * based upon cm_chunkSize but we desire cm_chunkSize to be large
+ * so that we can read larger amounts of data at a time.
*/
- if ((thyper.LowPart & (-cm_chunkSize)) !=
- (offset.LowPart & (-cm_chunkSize))) {
+ if (smb_AsyncStore == 1 &&
+ (thyper.LowPart & ~(smb_AsyncStoreSize-1)) !=
+ (offset.LowPart & ~(smb_AsyncStoreSize-1))) {
/* they're different */
doWriteBack = 1;
writeBackOffset.HighPart = offset.HighPart;
- writeBackOffset.LowPart = offset.LowPart & (-cm_chunkSize);
+ writeBackOffset.LowPart = offset.LowPart & ~(smb_AsyncStoreSize-1);
}
-
+
*writtenp = count;
/* now, copy the data one buffer at a time, until we've filled the
buf_Release(bufferp);
bufferp = NULL;
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
- lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &thyper, &bufferp);
- lock_ReleaseRead(&scp->bufCreateLock);
lock_ObtainMutex(&bufferp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if (code) goto done;
bufferOffset = thyper;
if (code)
goto done;
+ cm_SyncOpDone(scp, bufferp,
+ CM_SCACHESYNC_NEEDCALLBACK
+ | CM_SCACHESYNC_WRITE
+ | CM_SCACHESYNC_BUFLOCKED);
+
/* If we're overwriting the entire buffer, or
* if we're writing at or past EOF, mark the
* buffer as current so we don't call
ConvertLongToLargeInteger(count)),
minLength))) {
if (count < cm_data.buf_blockSize
- && bufferp->dataVersion == -1)
+ && bufferp->dataVersion == CM_BUF_VERSION_BAD)
memset(bufferp->datap, 0,
cm_data.buf_blockSize);
bufferp->dataVersion = scp->dataVersion;
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp,
&req);
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
lock_ObtainMutex(&bufferp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
if (code) break;
}
if (code) {
nbytes = count; /* don't go past end of request */
/* now copy the data */
-#ifdef DJGPP
- if (dosflag)
- dosmemget((dos_ptr)op, nbytes, bufferp->datap + bufIndex);
- else
-#endif /* DJGPP */
- memcpy(bufferp->datap + bufIndex, op, nbytes);
- buf_SetDirty(bufferp);
+ memcpy(bufferp->datap + bufIndex, op, nbytes);
+ buf_SetDirty(bufferp, bufIndex, nbytes);
/* and record the last writer */
if (bufferp->userp != userp) {
} /* while 1 */
done:
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
if (bufferp) {
lock_ReleaseMutex(&bufferp->mx);
}
lock_ReleaseMutex(&fidp->mx);
- if (code == 0 && doWriteBack) {
- long code2;
- lock_ObtainMutex(&scp->mx);
- osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE",
- fidp->fid);
- code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE);
- osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns 0x%x",
- fidp->fid, code2);
- lock_ReleaseMutex(&scp->mx);
- cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
- writeBackOffset.HighPart, cm_chunkSize, 0, userp);
+ if (code == 0) {
+ if (smb_AsyncStore > 0) {
+ if (doWriteBack) {
+ long code2;
+
+ lock_ObtainWrite(&scp->rw);
+ osi_Log1(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE",
+ fidp->fid);
+ code2 = cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE);
+ osi_Log2(smb_logp, "smb_WriteData fid %d calling cm_SyncOp ASYNCSTORE returns 0x%x",
+ fidp->fid, code2);
+ lock_ReleaseWrite(&scp->rw);
+ cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
+ writeBackOffset.HighPart,
+ smb_AsyncStoreSize, 0, userp);
+ /* cm_SyncOpDone is called at the completion of cm_BkgStore */
+ }
+ } else {
+ cm_BufWrite(scp, offsetp, *writtenp, 0, userp, &req);
+ }
}
cm_ReleaseSCache(scp);
+ done2:
osi_Log3(smb_logp, "smb_WriteData fid %d returns 0x%x written %d bytes",
fidp->fid, code, *writtenp);
return code;
}
+/* SMB_COM_WRITE */
long smb_ReceiveCoreWrite(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- osi_hyper_t offset;
- long count, written = 0, total_written = 0;
unsigned short fd;
+ unsigned short count;
+ osi_hyper_t offset;
+ unsigned short hint;
+ long written = 0, total_written = 0;
unsigned pid;
smb_fid_t *fidp;
+ smb_t* smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
cm_attr_t truncAttr; /* attribute struct used for truncating file */
fd = smb_GetSMBParm(inp, 0);
count = smb_GetSMBParm(inp, 1);
offset.HighPart = 0; /* too bad */
- offset.LowPart = smb_GetSMBParm(inp, 2) | (smb_GetSMBParm(inp, 3) << 16);
+ offset.LowPart = smb_GetSMBParmLong(inp, 2);
+ hint = smb_GetSMBParm(inp, 4);
op = smb_GetSMBData(inp, NULL);
op = smb_ParseDataBlock(op, NULL, &inDataBlockCount);
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
- if (!fidp)
+ if (!fidp) {
+ osi_Log0(smb_logp, "smb_ReceiveCoreWrite fid not found");
return CM_ERROR_BADFD;
+ }
+ if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
+ smb_CloseFID(vcp, fidp, NULL, 0);
+ smb_ReleaseFID(fidp);
+ return CM_ERROR_NOSUCHFILE;
+ }
+
lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL) {
lock_ReleaseMutex(&fidp->mx);
code = smb_IoctlWrite(fidp, vcp, inp, outp);
smb_ReleaseFID(fidp);
+ osi_Log1(smb_logp, "smb_ReceiveCoreWrite ioctl code 0x%x", code);
return code;
}
lock_ReleaseMutex(&fidp->mx);
userp = smb_GetUserFromVCP(vcp, inp);
- /* special case: 0 bytes transferred means truncate to this position */
- if (count == 0) {
- cm_req_t req;
-
- cm_InitReq(&req);
-
- truncAttr.mask = CM_ATTRMASK_LENGTH;
- truncAttr.length.LowPart = offset.LowPart;
- 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);
- goto done;
- }
-
{
cm_key_t key;
LARGE_INTEGER LOffset;
LARGE_INTEGER LLength;
- pid = ((smb_t *) inp)->pid;
+ pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = offset.HighPart;
LLength.HighPart = 0;
LLength.LowPart = count;
- lock_ObtainMutex(&fidp->scp->mx);
+ lock_ObtainWrite(&fidp->scp->rw);
code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
- lock_ReleaseMutex(&fidp->scp->mx);
+ lock_ReleaseWrite(&fidp->scp->rw);
- if (code)
+ if (code) {
+ osi_Log1(smb_logp, "smb_ReceiveCoreWrite lock check failure 0x%x", code);
goto done;
+ }
+ }
+
+ /* special case: 0 bytes transferred means truncate to this position */
+ if (count == 0) {
+ cm_req_t req;
+
+ osi_Log1(smb_logp, "smb_ReceiveCoreWrite truncation to length 0x%x", offset.LowPart);
+
+ cm_InitReq(&req);
+
+ truncAttr.mask = CM_ATTRMASK_LENGTH;
+ truncAttr.length.LowPart = offset.LowPart;
+ 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, 0 /* count */);
+ smb_SetSMBDataLength(outp, 0);
+ goto done;
}
/*
code = 0;
while ( code == 0 && count > 0 ) {
-#ifndef DJGPP
code = smb_WriteData(fidp, &offset, count, op, userp, &written);
-#else /* DJGPP */
- code = smb_WriteData(fidp, &offset, count, op, userp, &written, FALSE);
-#endif /* !DJGPP */
if (code == 0 && written == 0)
code = CM_ERROR_PARTIALWRITE;
- offset.LowPart += written;
- count -= written;
+ offset = LargeIntegerAdd(offset,
+ ConvertLongToLargeInteger(written));
+ count -= (unsigned short)written;
total_written += written;
written = 0;
}
+ osi_Log2(smb_logp, "smb_ReceiveCoreWrite total written 0x%x code 0x%x",
+ total_written, code);
+
/* set the packet data length to 3 bytes for the data block header,
* plus the size of the data.
*/
smb_SetSMBParm(outp, 0, total_written);
+ smb_SetSMBParmLong(outp, 1, offset.LowPart);
+ smb_SetSMBParm(outp, 3, hint);
smb_SetSMBDataLength(outp, 0);
done:
unsigned short fd;
smb_fid_t *fidp;
cm_user_t *userp;
-#ifndef DJGPP
char *rawBuf;
-#else /* DJGPP */
- dos_ptr rawBuf;
-#endif /* !DJGPP */
long written = 0;
long code = 0;
fd = smb_GetSMBParm(inp, 0);
fidp = smb_FindFID(vcp, fd, 0);
- osi_Log2(smb_logp, "Completing Raw Write offset %x count %x",
- rwcp->offset.LowPart, rwcp->count);
+ if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
+ smb_CloseFID(vcp, fidp, NULL, 0);
+ smb_ReleaseFID(fidp);
+ return;
+ }
+
+ osi_Log3(smb_logp, "Completing Raw Write offset 0x%x:%08x count %x",
+ rwcp->offset.HighPart, rwcp->offset.LowPart, rwcp->count);
userp = smb_GetUserFromVCP(vcp, inp);
-#ifndef DJGPP
rawBuf = rwcp->buf;
code = smb_WriteData(fidp, &rwcp->offset, rwcp->count, rawBuf, userp,
&written);
-#else /* DJGPP */
- rawBuf = (dos_ptr) rwcp->buf;
- code = smb_WriteData(fidp, &rwcp->offset, rwcp->count,
- (unsigned char *) rawBuf, userp,
- &written, TRUE);
-#endif /* !DJGPP */
-
if (rwcp->writeMode & 0x1) { /* synchronous */
smb_t *op;
/* Give back raw buffer */
lock_ObtainMutex(&smb_RawBufLock);
-#ifndef DJGPP
*((char **)rawBuf) = smb_RawBufs;
-#else /* DJGPP */
- _farpokel(_dos_ds, rawBuf, smb_RawBufs);
-#endif /* !DJGPP */
smb_RawBufs = rawBuf;
lock_ReleaseMutex(&smb_RawBufLock);
return 0;
}
+/* SMB_COM_WRITE_RAW */
long smb_ReceiveCoreWriteRaw(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp, raw_write_cont_t *rwcp)
{
osi_hyper_t offset;
long totalCount;
unsigned short fd;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
char *op;
unsigned short writeMode;
-#ifndef DJGPP
char *rawBuf;
-#else /* DJGPP */
- dos_ptr rawBuf;
-#endif /* !DJGPP */
-
fd = smb_GetSMBParm(inp, 0);
totalCount = smb_GetSMBParm(inp, 1);
count = smb_GetSMBParm(inp, 10);
- offset.HighPart = 0; /* too bad */
- offset.LowPart = smb_GetSMBParm(inp, 3) | (smb_GetSMBParm(inp, 4) << 16);
writeMode = smb_GetSMBParm(inp, 7);
op = (char *) inp->data;
op += smb_GetSMBParm(inp, 11);
+ offset.HighPart = 0;
+ offset.LowPart = smb_GetSMBParm(inp, 3) | (smb_GetSMBParm(inp, 4) << 16);
+
+ if (*inp->wctp == 14) {
+ /* we received a 64-bit file offset */
+#ifdef AFS_LARGEFILES
+ offset.HighPart = smb_GetSMBParm(inp, 12) | (smb_GetSMBParm(inp, 13) << 16);
+
+ if (LargeIntegerLessThanZero(offset)) {
+ osi_Log2(smb_logp,
+ "smb_ReceiveCoreWriteRaw received negative file offset 0x%x:%08x",
+ offset.HighPart, offset.LowPart);
+ return CM_ERROR_BADSMB;
+ }
+#else
+ if ((smb_GetSMBParm(inp, 12) | (smb_GetSMBParm(inp, 13) << 16)) != 0) {
+ osi_Log0(smb_logp,
+ "smb_ReceiveCoreWriteRaw received 64-bit file offset, but we don't support large files");
+ return CM_ERROR_BADSMB;
+ }
+
+ offset.HighPart = 0;
+#endif
+ } else {
+ offset.HighPart = 0; /* 32-bit file offset */
+ }
+
osi_Log4(smb_logp,
- "smb_ReceiveCoreWriteRaw fd %d, off 0x%x, size 0x%x, WriteMode 0x%x",
- fd, offset.LowPart, count, writeMode);
+ "smb_ReceiveCoreWriteRaw fd %d, off 0x%x:%08x, size 0x%x",
+ fd, offset.HighPart, offset.LowPart, count);
+ osi_Log1(smb_logp,
+ " WriteRaw WriteMode 0x%x",
+ writeMode);
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
return CM_ERROR_BADFD;
}
+ if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
+ smb_CloseFID(vcp, fidp, NULL, 0);
+ smb_ReleaseFID(fidp);
+ return CM_ERROR_NOSUCHFILE;
+ }
+
{
unsigned pid;
cm_key_t key;
LARGE_INTEGER LOffset;
LARGE_INTEGER LLength;
- pid = ((smb_t *) inp)->pid;
+ pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = offset.HighPart;
LLength.HighPart = 0;
LLength.LowPart = count;
- lock_ObtainMutex(&fidp->scp->mx);
+ lock_ObtainWrite(&fidp->scp->rw);
code = cm_LockCheckWrite(fidp->scp, LOffset, LLength, key);
- lock_ReleaseMutex(&fidp->scp->mx);
+ lock_ReleaseWrite(&fidp->scp->rw);
if (code) {
smb_ReleaseFID(fidp);
code = 0;
while ( code == 0 && count > 0 ) {
-#ifndef DJGPP
code = smb_WriteData(fidp, &offset, count, op, userp, &written);
-#else /* DJGPP */
- code = smb_WriteData(fidp, &offset, count, op, userp, &written, FALSE);
-#endif /* !DJGPP */
if (code == 0 && written == 0)
code = CM_ERROR_PARTIALWRITE;
- offset.LowPart += written;
+ offset = LargeIntegerAdd(offset,
+ ConvertLongToLargeInteger(written));
+
count -= written;
total_written += written;
written = 0;
if (smb_RawBufs) {
/* Get a raw buf, from head of list */
rawBuf = smb_RawBufs;
-#ifndef DJGPP
smb_RawBufs = *(char **)smb_RawBufs;
-#else /* DJGPP */
- smb_RawBufs = _farpeekl(_dos_ds, smb_RawBufs);
-#endif /* !DJGPP */
}
else
code = CM_ERROR_USESTD;
return code;
}
+ offset = LargeIntegerAdd(offset,
+ ConvertLongToLargeInteger(count));
+
rwcp->code = 0;
rwcp->buf = rawBuf;
- rwcp->offset.HighPart = 0;
- rwcp->offset.LowPart = offset.LowPart + count;
+ rwcp->offset.HighPart = offset.HighPart;
+ rwcp->offset.LowPart = offset.LowPart;
rwcp->count = totalCount - count;
rwcp->writeMode = writeMode;
rwcp->alreadyWritten = total_written;
return 0;
}
+/* SMB_COM_READ */
long smb_ReceiveCoreRead(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
osi_hyper_t offset;
unsigned short fd;
unsigned pid;
smb_fid_t *fidp;
+ smb_t *smbp = (smb_t*) inp;
long code = 0;
cm_user_t *userp;
char *op;
if (!fidp)
return CM_ERROR_BADFD;
+ if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
+ smb_CloseFID(vcp, fidp, NULL, 0);
+ smb_ReleaseFID(fidp);
+ return CM_ERROR_NOSUCHFILE;
+ }
+
lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL) {
lock_ReleaseMutex(&fidp->mx);
LARGE_INTEGER LOffset, LLength;
cm_key_t key;
- pid = ((smb_t *) inp)->pid;
+ pid = smbp->pid;
key = cm_GenerateKey(vcp->vcID, pid, fd);
LOffset.HighPart = 0;
LLength.HighPart = 0;
LLength.LowPart = count;
- lock_ObtainMutex(&fidp->scp->mx);
+ lock_ObtainWrite(&fidp->scp->rw);
code = cm_LockCheckRead(fidp->scp, LOffset, LLength, key);
- lock_ReleaseMutex(&fidp->scp->mx);
+ lock_ReleaseWrite(&fidp->scp->rw);
}
if (code) {
smb_ReleaseFID(fidp);
*op++ = (unsigned char) (count & 0xff);
*op++ = (unsigned char) ((count >> 8) & 0xff);
-#ifndef DJGPP
code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount);
-#else /* DJGPP */
- code = smb_ReadData(fidp, &offset, count, op, userp, &finalCount, FALSE);
-#endif /* !DJGPP */
/* fix some things up */
smb_SetSMBParm(outp, 0, finalCount);
return code;
}
+/* SMB_COM_CREATE_DIRECTORY */
long smb_ReceiveCoreMakeDir(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- char *pathp;
+ clientchar_t *pathp;
long code = 0;
cm_space_t *spacep;
- char *tp;
+ unsigned char *tp;
cm_user_t *userp;
cm_scache_t *dscp; /* dir we're dealing with */
cm_scache_t *scp; /* file we're creating */
cm_attr_t setAttr;
int initialModeBits;
- char *lastNamep;
+ clientchar_t *lastNamep;
int caseFold;
- char *tidPathp;
+ clientchar_t *tidPathp;
cm_req_t req;
cm_InitReq(&req);
initialModeBits = 0777;
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
- if (strcmp(pathp, "\\") == 0)
+ if (cm_ClientStrCmp(pathp, _C("\\")) == 0)
return CM_ERROR_EXISTS;
spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, &lastNamep, pathp);
+ smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
userp = smb_GetUserFromVCP(vcp, inp);
return CM_ERROR_NOSUCHPATH;
}
- code = cm_NameI(cm_data.rootSCachep, spacep->data,
+ code = cm_NameI(cm_data.rootSCachep, spacep->wdata,
caseFold | CM_FLAG_FOLLOW | CM_FLAG_CHECKPATH,
userp, tidPathp, &req, &dscp);
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
lastNamep++;
code = cm_Lookup(dscp, lastNamep, 0, userp, &req, &scp);
if (scp) cm_ReleaseSCache(scp);
- if (code != CM_ERROR_NOSUCHFILE) {
+ if (code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH) {
if (code == 0) code = CM_ERROR_EXISTS;
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
return 0;
}
-BOOL smb_IsLegalFilename(char *filename)
+BOOL smb_IsLegalFilename(clientchar_t *filename)
{
/*
* Find the longest substring of filename that does not contain
* than the length of the whole string, then one or more of the
* illegal chars is in filename.
*/
- if (strcspn(filename, illegalChars) < strlen(filename))
+ if (cm_ClientStrCSpn(filename, illegalChars) < cm_ClientStrLen(filename))
return FALSE;
return TRUE;
-}
+}
+/* SMB_COM_CREATE and SMB_COM_CREATE_NEW */
long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
- char *pathp;
+ clientchar_t *pathp;
long code = 0;
cm_space_t *spacep;
- char *tp;
+ unsigned char *tp;
int excl;
cm_user_t *userp;
cm_scache_t *dscp; /* dir we're dealing with */
int initialModeBits;
smb_fid_t *fidp;
int attributes;
- char *lastNamep;
+ clientchar_t *lastNamep;
int caseFold;
afs_uint32 dosTime;
- char *tidPathp;
+ clientchar_t *tidPathp;
cm_req_t req;
int created = 0; /* the file was new */
/* compute initial mode bits based on read-only flag in attributes */
initialModeBits = 0666;
- if (attributes & 1) initialModeBits &= ~0222;
+ if (attributes & SMB_ATTR_READONLY)
+ initialModeBits &= ~0222;
tp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(tp, &tp);
- if (smb_StoreAnsiFilenames)
- OemToChar(pathp,pathp);
+ pathp = smb_ParseASCIIBlock(inp, tp, &tp, SMB_STRF_ANSIPATH);
spacep = inp->spacep;
- smb_StripLastComponent(spacep->data, &lastNamep, pathp);
+ smb_StripLastComponent(spacep->wdata, &lastNamep, pathp);
userp = smb_GetUserFromVCP(vcp, inp);
cm_ReleaseUser(userp);
return CM_ERROR_NOSUCHPATH;
}
- code = cm_NameI(cm_data.rootSCachep, spacep->data, caseFold | CM_FLAG_FOLLOW,
+ code = cm_NameI(cm_data.rootSCachep, spacep->wdata, caseFold | CM_FLAG_FOLLOW,
userp, tidPathp, &req, &dscp);
if (code) {
#ifdef DFS_SUPPORT
if (dscp->fileType == CM_SCACHETYPE_DFSLINK) {
+ int pnc = cm_VolStatus_Notify_DFS_Mapping(dscp, tidPathp, spacep->wdata);
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
- if ( WANTS_DFS_PATHNAMES(inp) )
+ if ( WANTS_DFS_PATHNAMES(inp) || pnc )
return CM_ERROR_PATH_NOT_COVERED;
else
return CM_ERROR_BADSHARENAME;
if (!smb_IsLegalFilename(lastNamep))
return CM_ERROR_BADNTFILENAME;
- osi_Log1(smb_logp, "SMB receive create [%s]", osi_LogSaveString( smb_logp, pathp ));
+ osi_Log1(smb_logp, "SMB receive create [%S]", osi_LogSaveClientString( smb_logp, pathp ));
#ifdef DEBUG_VERBOSE
{
char *hexp;
#endif
code = cm_Lookup(dscp, lastNamep, 0, userp, &req, &scp);
- if (code && code != CM_ERROR_NOSUCHFILE) {
+ if (code && code != CM_ERROR_NOSUCHFILE && code != CM_ERROR_BPLUS_NOMATCH) {
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
return code;
created = 1;
if (dscp->flags & CM_SCACHEFLAG_ANYWATCH)
smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_FILE_NAME,
+ FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_CREATION,
dscp, lastNamep, NULL, TRUE);
} else if (!excl && code == CM_ERROR_EXISTS) {
/* not an exclusive create, and someone else tried
/* now all we have to do is open the file itself */
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
- osi_assert(fidp);
+ osi_assertx(fidp, "null smb_fid_t");
cm_HoldUser(userp);
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_ObtainWrite(&scp->rw);
+ scp->flags |= CM_SCACHEFLAG_SMB_FID;
+ lock_ReleaseWrite(&scp->rw);
+
/* and the user */
fidp->userp = userp;
lock_ReleaseMutex(&fidp->mx);
return 0;
}
+/* SMB_COM_SEEK */
long smb_ReceiveCoreSeek(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
{
long code = 0;
+ osi_hyper_t new_offset;
long offset;
int whence;
unsigned short fd;
/* try to find the file descriptor */
fd = smb_ChainFID(fd, inp);
fidp = smb_FindFID(vcp, fd, 0);
-
if (!fidp)
return CM_ERROR_BADFD;
+ if (fidp->scp && (fidp->scp->flags & CM_SCACHEFLAG_DELETED)) {
+ smb_CloseFID(vcp, fidp, NULL, 0);
+ smb_ReleaseFID(fidp);
+ return CM_ERROR_NOSUCHFILE;
+ }
+
lock_ObtainMutex(&fidp->mx);
if (fidp->flags & SMB_FID_IOCTL) {
lock_ReleaseMutex(&fidp->mx);
scp = fidp->scp;
cm_HoldSCache(scp);
lock_ReleaseMutex(&fidp->mx);
- lock_ObtainMutex(&scp->mx);
+ lock_ObtainWrite(&scp->rw);
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code == 0) {
+ cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (whence == 1) {
/* offset from current offset */
- offset += fidp->offset;
+ new_offset = LargeIntegerAdd(fidp->offset,
+ ConvertLongToLargeInteger(offset));
}
else if (whence == 2) {
/* offset from current EOF */
- offset += scp->length.LowPart;
+ new_offset = LargeIntegerAdd(scp->length,
+ ConvertLongToLargeInteger(offset));
+ } else {
+ new_offset = ConvertLongToLargeInteger(offset);
}
- fidp->offset = offset;
- smb_SetSMBParm(outp, 0, offset & 0xffff);
- smb_SetSMBParm(outp, 1, (offset>>16) & 0xffff);
+
+ fidp->offset = new_offset;
+ smb_SetSMBParm(outp, 0, new_offset.LowPart & 0xffff);
+ smb_SetSMBParm(outp, 1, (new_offset.LowPart>>16) & 0xffff);
smb_SetSMBDataLength(outp, 0);
}
- lock_ReleaseMutex(&scp->mx);
+ lock_ReleaseWrite(&scp->rw);
smb_ReleaseFID(fidp);
cm_ReleaseSCache(scp);
cm_ReleaseUser(userp);
/* Sanity check */
if (ncbp->ncb_length < offsetof(struct smb, vdata)) {
/* log it and discard it */
-#ifndef DJGPP
LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_TOO_SHORT,
__FILE__, __LINE__, ncbp->ncb_length);
-#endif /* !DJGPP */
osi_Log1(smb_logp, "SMB message too short, len %d", ncbp->ncb_length);
return;
}
if (dp->procp) {
/* we have a recognized operation */
+ char * opName = myCrt_Dispatch(inp->inCom);
if (inp->inCom == 0x1d)
/* Raw Write */
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);
+ osi_Log4(smb_logp,"Dispatch %s vcp 0x%p lana %d lsn %d",
+ opName,vcp,vcp->lana,vcp->lsn);
code = (*(dp->procp)) (vcp, inp, outp);
- osi_Log4(smb_logp,"Dispatch return code 0x%x vcp 0x%p lana %d lsn %d",code,vcp,vcp->lana,vcp->lsn);
+ osi_Log4(smb_logp,"Dispatch return code 0x%x vcp 0x%p lana %d lsn %d",
+ code,vcp,vcp->lana,vcp->lsn);
#ifdef LOG_PACKET
if ( code == CM_ERROR_BADSMB ||
code == CM_ERROR_BADOP )
- smb_LogPacket(inp);
+ smb_LogPacket(inp);
#endif /* LOG_PACKET */
}
+ newTime = GetTickCount();
+ osi_Log2(smb_logp, "Dispatch %s duration %d ms", opName, newTime - oldTime);
+
if (oldGen != sessionGen) {
- newTime = GetTickCount();
-#ifndef DJGPP
LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_WRONG_SESSION,
newTime - oldTime, ncbp->ncb_length);
-#endif /* !DJGPP */
- osi_Log2(smb_logp, "Pkt straddled session startup, "
- "took %d ms, ncb length %d", newTime - oldTime, ncbp->ncb_length);
+ osi_Log3(smb_logp, "Request %s straddled session startup, "
+ "took %d ms, ncb length %d", opName, newTime - oldTime, ncbp->ncb_length);
}
- }
- else {
+
+ FreeSMBStrings(inp);
+ } else {
/* bad opcode, fail the request, after displaying it */
osi_Log1(smb_logp, "Received bad SMB req 0x%X", inp->inCom);
#ifdef LOG_PACKET
smb_LogPacket(inp);
#endif /* LOG_PACKET */
-#ifndef DJGPP
if (showErrors) {
sprintf(tbuffer, "Received bad SMB req 0x%x", inp->inCom);
code = (*smb_MBfunc)(NULL, tbuffer, "Cancel: don't show again",
if (code == IDCANCEL)
showErrors = 0;
}
-#endif /* DJGPP */
code = CM_ERROR_BADOP;
}
/* catastrophic failure: log as much as possible */
if (code == CM_ERROR_BADSMB) {
-#ifndef DJGPP
LogEvent(EVENTLOG_WARNING_TYPE, MSG_BAD_SMB_INVALID,
ncbp->ncb_length);
-#endif /* !DJGPP */
#ifdef LOG_PACKET
smb_LogPacket(inp);
#endif /* LOG_PACKET */
return;
}
-#ifndef DJGPP
/* Wait for Netbios() calls to return, and make the results available to server
* threads. Note that server threads can't wait on the NCBevents array
* themselves, because NCB events are manual-reset, and the servers would race
{
/* this is fatal - log as much as possible */
osi_Log1(smb_logp, "Fatal: NCBevents idx [ %d ] out of range.\n", idx);
- osi_assert(0);
+ osi_assertx(0, "invalid index");
}
thrd_ResetEvent(NCBevents[idx]);
thrd_SetEvent(NCBreturns[0][idx]);
}
}
-#endif /* !DJGPP */
/*
* Try to have one NCBRECV request waiting for every live session. Not more
DWORD code;
int idx_session, idx_NCB;
NCB *ncbp;
-#ifdef DJGPP
- dos_ptr dos_ncb;
-#endif /* DJGPP */
while (smbShutdownFlag == 0) {
/* Get a session */
{
/* this is fatal - log as much as possible */
osi_Log1(smb_logp, "Fatal: session idx [ %d ] out of range.\n", idx_session);
- osi_assert(0);
+ osi_assertx(0, "invalid index");
}
/* Get an NCB */
{
/* this is fatal - log as much as possible */
osi_Log1(smb_logp, "Fatal: idx_NCB [ %d ] out of range.\n", idx_NCB);
- osi_assert(0);
+ osi_assertx(0, "invalid index");
}
/* Link them together */
ncbp->ncb_lsn = (unsigned char) LSNs[idx_session];
ncbp->ncb_command = NCBRECV | ASYNCH;
ncbp->ncb_lana_num = lanas[idx_session];
-#ifndef DJGPP
ncbp->ncb_buffer = (unsigned char *) bufs[idx_NCB];
ncbp->ncb_event = NCBevents[idx_NCB];
ncbp->ncb_length = SMB_PACKETSIZE;
Netbios(ncbp);
-#else /* DJGPP */
- ncbp->ncb_buffer = bufs[idx_NCB]->dos_pkt;
- ((smb_ncb_t*)ncbp)->orig_pkt = bufs[idx_NCB];
- ncbp->ncb_event = NCBreturns[0][idx_NCB];
- ncbp->ncb_length = SMB_PACKETSIZE;
- dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
- Netbios(ncbp, dos_ncb);
-#endif /* !DJGPP */
}
}
UCHAR rc;
smb_vc_t *vcp = NULL;
smb_t *smbp;
-#ifdef DJGPP
- dos_ptr dos_ncb;
-#endif /* DJGPP */
+ extern void rx_StartClientThread(void);
rx_StartClientThread();
{
/* this is fatal - log as much as possible */
osi_Log1(smb_logp, "Fatal: idx_NCB %d out of range.\n", idx_NCB);
- osi_assert(0);
+ osi_assertx(0, "invalid index");
}
ncbp = NCBs[idx_NCB];
-#ifdef DJGPP
- dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
-#endif /* DJGPP */
idx_session = NCBsessions[idx_NCB];
rc = ncbp->ncb_retcode;
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 */
vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
case NRC_INCOMP:
/* Treat as transient error */
-#ifndef DJGPP
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);
vcp->errorCount = 0;
bufp = (struct smb_packet *) ncbp->ncb_buffer;
-#ifdef DJGPP
- bufp = ((smb_ncb_t *) ncbp)->orig_pkt;
- /* copy whole packet to virtual memory */
- /*fprintf(stderr, "smb_Server: copying dos packet at 0x%x, "
- "bufp=0x%x\n",
- bufp->dos_pkt / 16, bufp);*/
- fflush(stderr);
- dosmemget(bufp->dos_pkt, ncbp->ncb_length, bufp->data);
-#endif /* DJGPP */
smbp = (smb_t *)bufp->data;
outbufp->flags = 0;
-#if !defined(DJGPP) && !defined(AFS_WIN32_ENV)
+#ifndef NOTRACE
__try
{
#endif
ncbp->ncb_buffer = rwc.buf;
ncbp->ncb_length = 65535;
ncbp->ncb_event = rwevent;
-#ifndef DJGPP
Netbios(ncbp);
-#else
- Netbios(ncbp, dos_ncb);
-#endif /* !DJGPP */
rcode = thrd_WaitForSingleObject_Event(rwevent, RAWTIMEOUT);
thrd_CloseHandle(rwevent);
}
/* TODO: what else needs to be serialized? */
smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL);
}
-#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
+#ifndef NOTRACE
}
__except( smb_ServerExceptionFilter() ) {
}
* force trace and give control to upstream exception handlers. Useful for
* debugging.
*/
-#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
DWORD smb_ServerExceptionFilter(void) {
/* While this is not the best time to do a trace, if it succeeds, then
* we have a trace (assuming tracing was enabled). Otherwise, this should
buf_ForceTrace(TRUE);
return EXCEPTION_CONTINUE_SEARCH;
}
-#endif
/*
* Create a new NCB and associated events, packet buffer, and "space" buffer.
{
struct smb_packet *bufp;
EVENT_HANDLE retHandle;
- int i;
+ afs_uint32 i;
char eventName[MAX_PATH];
- osi_assert( idx < (sizeof(NCBs) / sizeof(NCBs[0])) );
+ osi_assertx( idx < (sizeof(NCBs) / sizeof(NCBs[0])), "invalid index" );
NCBs[idx] = GetNCB();
sprintf(eventName,"NCBavails[%d]", idx);
NCBavails[idx] = 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));
-#ifndef DJGPP
sprintf(eventName,"NCBevents[%d]", idx);
NCBevents[idx] = thrd_CreateEvent(NULL, TRUE, FALSE, eventName);
if ( GetLastError() == ERROR_ALREADY_EXISTS )
osi_Log1(smb_logp, "Event Object Already Exists: %s", osi_LogSaveString(smb_logp, eventName));
-#endif /* !DJGPP */
sprintf(eventName,"NCBReturns[0<=i<smb_NumServerThreads][%d]", idx);
retHandle = thrd_CreateEvent(NULL, FALSE, FALSE, eventName);
if ( GetLastError() == ERROR_ALREADY_EXISTS )
long code = 0;
long len;
long i;
- int session, thread;
+ afs_uint32 session, thread;
smb_vc_t *vcp = NULL;
int flags = 0;
char rname[NCBNAMSZ+1];
char cname[MAX_COMPUTERNAME_LENGTH+1];
int cnamelen = MAX_COMPUTERNAME_LENGTH+1;
-#ifdef DJGPP
- dos_ptr dos_ncb;
- time_t now;
-#endif /* DJGPP */
INT_PTR lana = (INT_PTR) parmp;
+ char eventName[MAX_PATH];
+
+ sprintf(eventName,"smb_Listener_lana_%d", (unsigned char)lana);
+ ListenerShutdown[lana] = thrd_CreateEvent(NULL, FALSE, FALSE, eventName);
+ if ( GetLastError() == ERROR_ALREADY_EXISTS )
+ thrd_ResetEvent(ListenerShutdown[lana]);
ncbp = GetNCB();
-#ifdef DJGPP
- dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
-#endif /* DJGPP */
/* retrieve computer name */
GetComputerName(cname, &cnamelen);
_strupr(cname);
- while (1) {
+ while (smb_ListenerState == SMB_LISTENER_STARTED) {
memset(ncbp, 0, sizeof(NCB));
flags = 0;
ncbp->ncb_lana_num = (UCHAR)lana;
-#ifndef DJGPP
code = Netbios(ncbp);
-#else /* DJGPP */
- code = Netbios(ncbp, dos_ncb);
-#endif
- if (code != 0)
- {
-#ifndef DJGPP
- char tbuffer[256];
+ if (code == NRC_NAMERR) {
+ /* An smb shutdown or Vista resume must have taken place */
+ osi_Log2(smb_logp,
+ "NCBLISTEN lana=%d failed with NRC_NAMERR.",
+ ncbp->ncb_lana_num, code);
+
+ if (lock_TryMutex(&smb_StartedLock)) {
+ lana_list.lana[i] = LANA_INVALID;
+ lock_ReleaseMutex(&smb_StartedLock);
+ }
+ break;
+ } else if (code == NRC_BRIDGE || code != 0) {
+ int lanaRemaining = 0;
+
+ while (!lock_TryMutex(&smb_StartedLock)) {
+ if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1)
+ goto exit_thread;
+ Sleep(50);
+ }
+
+ osi_Log2(smb_logp,
+ "NCBLISTEN lana=%d failed with %s. Listener thread exiting.",
+ ncbp->ncb_lana_num, ncb_error_string(code));
+
+ for (i = 0; i < lana_list.length; i++) {
+ if (lana_list.lana[i] == lana) {
+ smb_StopListener(ncbp, lana_list.lana[i], FALSE);
+ lana_list.lana[i] = LANA_INVALID;
+ }
+ if (lana_list.lana[i] != LANA_INVALID)
+ lanaRemaining++;
+ }
+
+ if (lanaRemaining == 0) {
+ cm_VolStatus_Network_Stopped(cm_NetbiosName
+#ifdef _WIN64
+ ,cm_NetbiosName
#endif
+ );
+ smb_ListenerState = SMB_LISTENER_STOPPED;
+ smb_LANadapter = LANA_INVALID;
+ lana_list.length = 0;
+ }
+ lock_ReleaseMutex(&smb_StartedLock);
+ break;
+ }
+#if 0
+ else if (code != 0) {
+ char tbuffer[AFSPATHMAX];
/* terminate silently if shutdown flag is set */
- if (smbShutdownFlag == 1) {
-#ifndef DJGPP
- ExitThread(1);
-#else
- thrd_Exit(1);
-#endif
+ while (!lock_TryMutex(&smb_StartedLock)) {
+ if (smb_ListenerState == SMB_LISTENER_STOPPED || smbShutdownFlag == 1)
+ goto exit_thread;
+ Sleep(50);
}
- osi_Log2(smb_logp,
- "NCBLISTEN lana=%d failed with code %d",
- ncbp->ncb_lana_num, code);
+ osi_Log3(smb_logp,
+ "NCBLISTEN lana=%d failed with code %d [%s]",
+ ncbp->ncb_lana_num, code, ncb_error_string(code));
osi_Log0(smb_logp,
"Client exiting due to network failure. Please restart client.\n");
-#ifndef DJGPP
sprintf(tbuffer,
"Client exiting due to network failure. Please restart client.\n"
- "NCBLISTEN lana=%d failed with code %d",
- ncbp->ncb_lana_num, code);
+ "NCBLISTEN lana=%d failed with code %d [%s]",
+ ncbp->ncb_lana_num, code, ncb_error_string(code));
if (showErrors)
code = (*smb_MBfunc)(NULL, tbuffer, "AFS Client Service: Fatal Error",
MB_OK|MB_SERVICE_NOTIFICATION);
- osi_assert(tbuffer);
- ExitThread(1);
-#else
- fprintf(stderr, "NCBLISTEN lana=%d failed with code %d\n",
- ncbp->ncb_lana_num, code);
- fprintf(stderr, "\nClient exiting due to network failure "
- "(possibly due to power-saving mode)\n");
- fprintf(stderr, "Please restart client.\n");
- afs_exit(AFS_EXITCODE_NETWORK_FAILURE);
-#endif /* !DJGPP */
+ osi_panic(tbuffer, __FILE__, __LINE__);
+
+ lock_ReleaseMutex(&smb_StartedLock);
+ break;
}
+#endif /* 0 */
/* check for remote conns */
/* first get remote name and insert null terminator */
ncbp->ncb_lsn,ncbp->ncb_lana_num, osi_LogSaveString(smb_logp, rname), ongoingOps);
if (reportSessionStartups) {
-#ifndef DJGPP
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);
-#endif /* !DJGPP */
}
lock_ObtainMutex(&vcp->mx);
- strcpy(vcp->rname, rname);
+ cm_Utf8ToUtf16(rname, -1, vcp->rname, lengthof(vcp->rname));
vcp->flags |= flags;
lock_ReleaseMutex(&vcp->mx);
ncbp->ncb_lsn,ncbp->ncb_lana_num, osi_LogSaveString(smb_logp, rname), ongoingOps);
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 */
}
}
smbp->errHigh = (unsigned char) ((errCode >> 8) & 0xff);
smbp->rcls = errClass;
}
+
smb_SendPacket(vcp, outp);
smb_FreePacket(outp);
* 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 */
+ osi_assertx(session < SESSION_MAX - 1, "invalid session");
+ osi_assertx(numNCBs < NCB_MAX - 1, "invalid numNCBs"); /* if we pass this test we can allocate one more */
lock_ObtainMutex(&vcp->mx);
vcp->session = session;
/* unlock */
lock_ReleaseMutex(&smb_ListenerLock);
} /* dispatch while loop */
+
+exit_thread:
+ FreeNCB(ncbp);
+ thrd_SetEvent(ListenerShutdown[lana]);
+ return;
+}
+
+static void
+smb_LanAdapterChangeThread(void *param)
+{
+ /*
+ * Give the IPAddrDaemon thread a chance
+ * to block before we trigger.
+ */
+ Sleep(30000);
+ smb_LanAdapterChange(0);
+}
+
+void smb_SetLanAdapterChangeDetected(void)
+{
+ int lpid;
+ thread_t phandle;
+
+ lock_ObtainMutex(&smb_StartedLock);
+
+ if (!powerStateSuspended) {
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_LanAdapterChangeThread,
+ NULL, 0, &lpid, "smb_LanAdapterChange");
+ osi_assertx(phandle != NULL, "smb_LanAdapterChangeThread thread creation failure");
+ thrd_CloseHandle(phandle);
+ }
+
+ smb_LanAdapterChangeDetected = 1;
+ lock_ReleaseMutex(&smb_StartedLock);
+}
+
+void smb_LanAdapterChange(int locked) {
+ lana_number_t lanaNum;
+ BOOL bGateway;
+ char NetbiosName[MAX_NB_NAME_LENGTH] = "";
+ int change = 0;
+ LANA_ENUM temp_list;
+ long code;
+ int i;
+
+
+ afsi_log("smb_LanAdapterChange");
+
+ if (!locked)
+ lock_ObtainMutex(&smb_StartedLock);
+
+ smb_LanAdapterChangeDetected = 0;
+
+ if (!powerStateSuspended &&
+ SUCCEEDED(lana_GetUncServerNameEx(NetbiosName, &lanaNum, &bGateway,
+ LANA_NETBIOS_NAME_FULL)) &&
+ lanaNum != LANA_INVALID && smb_LANadapter != lanaNum) {
+ if ( isGateway != bGateway ||
+ strcmp(cm_NetbiosName, NetbiosName) ) {
+ change = 1;
+ } else {
+ NCB *ncbp = GetNCB();
+ ncbp->ncb_command = NCBENUM;
+ ncbp->ncb_buffer = (PUCHAR)&temp_list;
+ ncbp->ncb_length = sizeof(temp_list);
+ code = Netbios(ncbp);
+ if (code == 0) {
+ if (temp_list.length != lana_list.length)
+ change = 1;
+ else {
+ for (i=0; i<lana_list.length; i++) {
+ if ( temp_list.lana[i] != lana_list.lana[i] ) {
+ change = 1;
+ break;
+ }
+ }
+ }
+ }
+ FreeNCB(ncbp);
+ }
+ }
+
+ if (change) {
+ afsi_log("Lan Adapter Change detected");
+ smb_StopListeners(1);
+ smb_RestartListeners(1);
+ }
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
}
/* initialize Netbios */
-void smb_NetbiosInit()
+int smb_NetbiosInit(int locked)
{
NCB *ncbp;
-#ifdef DJGPP
- dos_ptr dos_ncb;
-#endif /* DJGPP */
int i, lana, code, l;
char s[100];
int delname_tried=0;
int len;
int lana_found = 0;
- OSVERSIONINFO Version;
+ lana_number_t lanaNum;
+
+ if (!locked)
+ lock_ObtainMutex(&smb_StartedLock);
- /* Get the version of Windows */
- memset(&Version, 0x00, sizeof(Version));
- Version.dwOSVersionInfoSize = sizeof(Version);
- GetVersionEx(&Version);
+ if (smb_ListenerState != SMB_LISTENER_UNINITIALIZED &&
+ smb_ListenerState != SMB_LISTENER_STOPPED) {
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
+ return 0;
+ }
/* setup the NCB system */
ncbp = GetNCB();
-#ifdef DJGPP
- dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
-#endif /* DJGPP */
-#ifndef DJGPP
- if (smb_LANadapter == -1) {
+ /* 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 != LANA_INVALID)
+ 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);
+
+ /* Also copy the value to the client character encoded string */
+ cm_Utf8ToClientString(cm_NetbiosName, -1, cm_NetbiosNameC, MAX_NB_NAME_LENGTH);
+
+ if (smb_LANadapter == LANA_INVALID) {
ncbp->ncb_command = NCBENUM;
ncbp->ncb_buffer = (PUCHAR)&lana_list;
ncbp->ncb_length = sizeof(lana_list);
code = ncbp->ncb_retcode;
if (code != 0) {
afsi_log("Netbios NCBRESET lana %d error code %d", lana_list.lana[i], code);
- lana_list.lana[i] = 255; /* invalid lana */
+ lana_list.lana[i] = LANA_INVALID; /* invalid lana */
} else {
afsi_log("Netbios NCBRESET lana %d succeeded", lana_list.lana[i]);
}
}
-#else
- /* for DJGPP, there is no NCBENUM and NCBRESET is a real reset. so
- we will just fake the LANA list */
- if (smb_LANadapter == -1) {
- for (i = 0; i < 8; i++)
- lana_list.lana[i] = i;
- lana_list.length = 8;
- }
- else {
- lana_list.length = 1;
- lana_list.lana[0] = smb_LANadapter;
- }
-#endif /* !DJGPP */
/* and declare our name so we can receive connections */
memset(ncbp, 0, sizeof(*ncbp));
ncbp->ncb_command = NCBADDNAME;
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 NCBADDNAME lana=%d code=%d retcode=%d complete=%d",
lana, code, ncbp->ncb_retcode, ncbp->ncb_cmd_cplt);
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);
-#ifdef DJGPP
- /* we only use one LANA with djgpp */
- lana_list.lana[0] = lana;
- lana_list.length = 1;
-#endif
}
else {
afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
if (code == NRC_BRIDGE) { /* invalid LANA num */
- lana_list.lana[l] = 255;
+ lana_list.lana[l] = LANA_INVALID;
continue;
}
else if (code == NRC_DUPNAME) {
ncbp->ncb_command = NCBDELNAME;
memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
ncbp->ncb_lana_num = lana;
-#ifndef DJGPP
code = Netbios(ncbp);
-#else
- code = Netbios(ncbp, dos_ncb);
-#endif /* DJGPP */
if (code == 0)
code = ncbp->ncb_retcode;
else {
afsi_log("Netbios NCBDELNAME lana %d error code %d\n", lana, code);
}
if (code != 0 || delname_tried) {
- lana_list.lana[l] = 255;
+ lana_list.lana[l] = LANA_INVALID;
}
else if (code == 0) {
if (!delname_tried) {
}
else {
afsi_log("Netbios NCBADDNAME lana %d error code %d", lana, code);
- lana_list.lana[l] = 255; /* invalid lana */
- osi_panic(s, __FILE__, __LINE__);
+ lana_list.lana[l] = LANA_INVALID; /* invalid lana */
}
}
if (code == 0) {
+ smb_LANadapter = lana;
lana_found = 1; /* at least one worked */
-#ifdef DJGPP
- break;
-#endif
}
}
- osi_assert(lana_list.length >= 0);
+ osi_assertx(lana_list.length >= 0, "empty lana list");
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 = LANA_INVALID;
+ 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);
+
+ afsi_log("smb_NetbiosInit smb_LANadapter=%d",smb_LANadapter);
+ if (lana_list.length > 0)
+ osi_assert(smb_LANadapter != LANA_INVALID);
+
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
+
+ return (lana_list.length > 0 ? 1 : 0);
+}
+
+void smb_StartListeners(int locked)
+{
+ int i;
+ int lpid;
+ thread_t phandle;
+
+ if (!locked)
+ lock_ObtainMutex(&smb_StartedLock);
+
+ if (smb_ListenerState == SMB_LISTENER_STARTED) {
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
+ return;
+ }
+
+ afsi_log("smb_StartListeners");
+ 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] == LANA_INVALID)
+ continue;
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_Listener,
+ (void*)lana_list.lana[i], 0, &lpid, "smb_Listener");
+ osi_assertx(phandle != NULL, "smb_Listener thread creation failure");
+ thrd_CloseHandle(phandle);
+ }
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
+}
+
+void smb_RestartListeners(int locked)
+{
+ if (!locked)
+ lock_ObtainMutex(&smb_StartedLock);
+
+ if (powerStateSuspended)
+ afsi_log("smb_RestartListeners called while suspended");
+
+ if (!powerStateSuspended && smb_ListenerState != SMB_LISTENER_UNINITIALIZED) {
+ if (smb_ListenerState == SMB_LISTENER_STOPPED) {
+ if (smb_NetbiosInit(1))
+ smb_StartListeners(1);
+ } else if (smb_LanAdapterChangeDetected) {
+ smb_LanAdapterChange(1);
+ }
+ }
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
+}
+
+void smb_StopListener(NCB *ncbp, int lana, int wait)
+{
+ 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);
+ }
+
+ if (wait)
+ thrd_WaitForSingleObject_Event(ListenerShutdown[lana], INFINITE);
+}
+
+void smb_StopListeners(int locked)
+{
+ NCB *ncbp;
+ int lana, l;
+
+ if (!locked)
+ lock_ObtainMutex(&smb_StartedLock);
+
+ if (smb_ListenerState == SMB_LISTENER_STOPPED) {
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
+ return;
+ }
+
+ afsi_log("smb_StopListeners");
+ 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 != LANA_INVALID) {
+ smb_StopListener(ncbp, lana, TRUE);
+
+ /* mark the adapter invalid */
+ lana_list.lana[l] = LANA_INVALID; /* invalid lana */
+ }
+ }
+
+ /* force a re-evaluation of the network adapters */
+ lana_list.length = 0;
+ smb_LANadapter = LANA_INVALID;
+ FreeNCB(ncbp);
+ if (!locked)
+ lock_ReleaseMutex(&smb_StartedLock);
}
-void smb_Init(osi_log_t *logp, char *snamep, int useV3, int LANadapt,
+void smb_Init(osi_log_t *logp, int useV3,
int nThreads
-#ifndef DJGPP
, void *aMBfunc
-#endif
)
{
thread_t phandle;
int lpid;
INT_PTR i;
- int len;
struct tm myTime;
-#ifdef DJGPP
- int npar, seg, sel;
- dos_ptr rawBuf;
-#endif /* DJGPP */
EVENT_HANDLE retHandle;
char eventName[MAX_PATH];
+ int startListeners = 0;
smb_TlsRequestSlot = TlsAlloc();
-#ifndef DJGPP
smb_MBfunc = aMBfunc;
-#endif /* DJGPP */
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");
lock_InitializeMutex(&smb_RawBufLock, "smb raw buffer lock");
lock_InitializeMutex(&smb_ListenerLock, "smb listener lock");
+ lock_InitializeMutex(&smb_StartedLock, "smb started lock");
/* 4 Raw I/O buffers */
-#ifndef DJGPP
smb_RawBufs = calloc(65536,1);
*((char **)smb_RawBufs) = NULL;
for (i=0; i<3; i++) {
*((char **)rawBuf) = smb_RawBufs;
smb_RawBufs = rawBuf;
}
-#else /* DJGPP */
- npar = 65536 >> 4; /* number of paragraphs */
- seg = __dpmi_allocate_dos_memory(npar, &smb_RawBufSel[0]);
- if (seg == -1) {
- afsi_log("Cannot allocate %d paragraphs of DOS memory",
- npar);
- osi_panic("",__FILE__,__LINE__);
- }
- else {
- afsi_log("Allocated %d paragraphs of DOS mem at 0x%X",
- npar, seg);
- }
- smb_RawBufs = (seg * 16) + 0; /* DOS physical address */
-
- _farpokel(_dos_ds, smb_RawBufs, NULL);
- for (i=0; i<SMB_RAW_BUFS-1; i++) {
- npar = 65536 >> 4; /* number of paragraphs */
- seg = __dpmi_allocate_dos_memory(npar, &smb_RawBufSel[i+1]);
- if (seg == -1) {
- afsi_log("Cannot allocate %d paragraphs of DOS memory",
- npar);
- osi_panic("",__FILE__,__LINE__);
- }
- else {
- afsi_log("Allocated %d paragraphs of DOS mem at 0x%X",
- npar, seg);
- }
- rawBuf = (seg * 16) + 0; /* DOS physical address */
- /*_farpokel(_dos_ds, smb_RawBufs, smb_RawBufs);*/
- _farpokel(_dos_ds, rawBuf, smb_RawBufs);
- smb_RawBufs = rawBuf;
- }
-#endif /* !DJGPP */
/* global free lists */
smb_ncbFreeListp = NULL;
smb_packetFreeListp = NULL;
- smb_NetbiosInit();
+ lock_ObtainMutex(&smb_StartedLock);
+ startListeners = smb_NetbiosInit(1);
/* Initialize listener and server structures */
numVCs = 0;
smb_dispatchTable[0x2d].flags |= SMB_DISPATCHFLAG_CHAINED;
smb_dispatchTable[0x2e].procp = smb_ReceiveV3ReadX;
smb_dispatchTable[0x2e].flags |= SMB_DISPATCHFLAG_CHAINED;
+ smb_dispatchTable[0x2f].procp = smb_ReceiveV3WriteX;
+ smb_dispatchTable[0x2f].flags |= SMB_DISPATCHFLAG_CHAINED;
smb_dispatchTable[0x32].procp = smb_ReceiveV3Tran2A; /* both are same */
smb_dispatchTable[0x32].flags |= SMB_DISPATCHFLAG_NORESPONSE;
smb_dispatchTable[0x33].procp = smb_ReceiveV3Tran2A;
smb_tran2DispatchTable[12].procp = smb_ReceiveTran2FindNotifyNext;
smb_tran2DispatchTable[13].procp = smb_ReceiveTran2CreateDirectory;
smb_tran2DispatchTable[14].procp = smb_ReceiveTran2SessionSetup;
+ smb_tran2DispatchTable[15].procp = smb_ReceiveTran2QFSInfoFid;
smb_tran2DispatchTable[16].procp = smb_ReceiveTran2GetDFSReferral;
smb_tran2DispatchTable[17].procp = smb_ReceiveTran2ReportDFSInconsistency;
* 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;
);
if (nts != STATUS_SUCCESS && ntsEx != STATUS_SUCCESS) {
- char message[256];
+ char message[AFSPATHMAX];
sprintf(message,"MsV1_0SetProcessOption failure: nts 0x%x ntsEx 0x%x",
nts, ntsEx);
OutputDebugString(message);
* It is actually the domain for local logins, and we are acting as
* a local SMB server.
*/
- bufsize = sizeof(smb_ServerDomainName) - 1;
- GetComputerName(smb_ServerDomainName, &bufsize);
+ bufsize = lengthof(smb_ServerDomainName) - 1;
+ GetComputerNameW(smb_ServerDomainName, &bufsize);
smb_ServerDomainNameLength = bufsize + 1; /* bufsize doesn't include terminator */
- afsi_log("Setting SMB server domain name to [%s]", smb_ServerDomainName);
+ afsi_log("Setting SMB server domain name to [%S]", smb_ServerDomainName);
}
/* Start listeners, waiters, servers, and daemons */
+ if (startListeners)
+ smb_StartListeners(1);
- 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);
- }
-
-#ifndef DJGPP
phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_ClientWaiter,
NULL, 0, &lpid, "smb_ClientWaiter");
- osi_assert(phandle != NULL);
+ osi_assertx(phandle != NULL, "smb_ClientWaiter thread creation failure");
thrd_CloseHandle(phandle);
-#endif /* !DJGPP */
phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_ServerWaiter,
NULL, 0, &lpid, "smb_ServerWaiter");
- osi_assert(phandle != NULL);
+ osi_assertx(phandle != NULL, "smb_ServerWaiter thread creation failure");
thrd_CloseHandle(phandle);
for (i=0; i<smb_NumServerThreads; i++) {
phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_Server,
(void *) i, 0, &lpid, "smb_Server");
- osi_assert(phandle != NULL);
+ osi_assertx(phandle != NULL, "smb_Server thread creation failure");
thrd_CloseHandle(phandle);
}
phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_Daemon,
NULL, 0, &lpid, "smb_Daemon");
- osi_assert(phandle != NULL);
+ osi_assertx(phandle != NULL, "smb_Daemon thread creation failure");
thrd_CloseHandle(phandle);
phandle = thrd_Create(NULL, 65536, (ThreadFunc) smb_WaitingLocksDaemon,
NULL, 0, &lpid, "smb_WaitingLocksDaemon");
- osi_assert(phandle != NULL);
+ osi_assertx(phandle != NULL, "smb_WaitingLocksDaemon thread creation failure");
thrd_CloseHandle(phandle);
-#ifdef DJGPP
- smb_ListShares();
-#endif
-
+ lock_ReleaseMutex(&smb_StartedLock);
return;
}
void smb_Shutdown(void)
{
NCB *ncbp;
-#ifdef DJGPP
- dos_ptr dos_ncb;
-#endif
long code = 0;
- int i;
+ afs_uint32 i;
smb_vc_t *vcp;
/*fprintf(stderr, "Entering smb_Shutdown\n");*/
/* setup the NCB system */
ncbp = GetNCB();
-#ifdef DJGPP
- dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
-#endif
/* Block new sessions by setting shutdown flag */
smbShutdownFlag = 1;
ncbp->ncb_command = NCBHANGUP;
ncbp->ncb_lana_num = lanas[i]; /*smb_LANadapter;*/
ncbp->ncb_lsn = (UCHAR)LSNs[i];
-#ifndef DJGPP
code = Netbios(ncbp);
-#else
- code = Netbios(ncbp, dos_ncb);
-#endif
/*fprintf(stderr, "returned from NCBHANGUP session %d LSN %d\n", i, LSNs[i]);*/
if (code == 0) code = ncbp->ncb_retcode;
if (code != 0) {
/* Delete Netbios name */
memset((char *)ncbp, 0, sizeof(NCB));
for (i = 0; i < lana_list.length; i++) {
- if (lana_list.lana[i] == 255) continue;
+ if (lana_list.lana[i] == LANA_INVALID) continue;
ncbp->ncb_command = NCBDELNAME;
ncbp->ncb_lana_num = lana_list.lana[i];
memcpy(ncbp->ncb_name,smb_sharename,NCBNAMSZ);
-#ifndef DJGPP
code = Netbios(ncbp);
-#else
- code = Netbios(ncbp, dos_ncb);
-#endif
if (code == 0)
code = ncbp->ncb_retcode;
if (code != 0) {
if (fidp->scp != NULL) {
scp = fidp->scp;
fidp->scp = NULL;
+ lock_ObtainWrite(&scp->rw);
+ scp->flags &= ~CM_SCACHEFLAG_SMB_FID;
+ lock_ReleaseWrite(&scp->rw);
+ osi_Log2(smb_logp,"smb_Shutdown fidp 0x%p scp 0x%p", fidp, scp);
cm_ReleaseSCache(scp);
}
lock_ReleaseMutex(&fidp->mx);
if (tidp->userp) {
cm_user_t *userp = tidp->userp;
tidp->userp = NULL;
- lock_ReleaseWrite(&smb_rctLock);
cm_ReleaseUser(userp);
- lock_ObtainWrite(&smb_rctLock);
}
}
}
lock_ReleaseWrite(&smb_rctLock);
-
+ FreeNCB(ncbp);
TlsFree(smb_TlsRequestSlot);
}
char *smb_GetSharename()
{
char *name;
+ int len;
/* Make sure we have been properly initialized. */
if (smb_localNamep == NULL)
/* Allocate space for \\<servername>\<sharename>, plus the
* terminator.
*/
- name = malloc(strlen(smb_localNamep) + strlen("ALL") + 4);
- sprintf(name, "\\\\%s\\%s", smb_localNamep, "ALL");
+ len = (strlen(smb_localNamep) + strlen("ALL") + 4) * sizeof(char);
+ name = malloc(len);
+ snprintf(name, len, "\\\\%s\\%s", smb_localNamep, "ALL");
return name;
-}
+}
#ifdef LOG_PACKET
void smb_LogPacket(smb_packet_t *packet)
{
BYTE *vp, *cp;
+ smb_t * smbp;
unsigned length, paramlen, datalen, i, j;
char buf[81];
char hex[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
osi_Log0(smb_logp, "*** SMB packet dump ***");
+ smbp = (smb_t *) packet->data;
vp = (BYTE *) packet->data;
- datalen = *((WORD*)(vp + (paramlen = ((unsigned)*(vp+20)) << 1)));
- length = paramlen + 2 + datalen;
-
+ paramlen = smbp->wct * 2;
+ datalen = *((WORD *) (smbp->vdata + paramlen));
+ length = sizeof(*smbp) + paramlen + 1 + datalen;
for (i=0;i < length; i+=16)
{
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",
- 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 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",
+ 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");
+ fidp->NTopen_pathp ? fidp->NTopen_pathp : _C("NULL"),
+ fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : _C("NULL"));
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
- sprintf(output, "done dumping smb_fid_t\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");
+ 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");
+ fidp->NTopen_pathp ? fidp->NTopen_pathp : _C("NULL"),
+ fidp->NTopen_wholepathp ? fidp->NTopen_wholepathp : _C("NULL"));
WriteFile(outputFile, output, (DWORD)strlen(output), &zilch, NULL);
}
- sprintf(output, "done dumping smb_fid_t\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");
+ 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)
+{
+ long rc;
+ lock_ObtainWrite(&smb_globalLock);
+ rc = (smb_ListenerState == SMB_LISTENER_STARTED && smbShutdownFlag == 0);
+ lock_ReleaseWrite(&smb_globalLock);
+ return rc;
+}