From 94e2fd2f51b671ee44e9ddd12b44c6d26aa149fe Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 17 Jul 2006 19:45:27 +0000 Subject: [PATCH] windows-cifs-rewrite-20060717 a re-write of the Tran2 Query File Info, Query Path Info, Set File Info, and Set Path Info functions to make them more readable and ensure correctness. --- src/WINNT/afsd/smb.c | 7 +- src/WINNT/afsd/smb.h | 29 ++- src/WINNT/afsd/smb3.c | 564 ++++++++++++++++++++++++++++-------------- src/WINNT/afsd/smb3.h | 134 +++++++++- 4 files changed, 539 insertions(+), 195 deletions(-) diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 831f1bd42..725234051 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -4655,12 +4655,12 @@ long smb_ReceiveCoreSetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack 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; @@ -7009,7 +7009,8 @@ long smb_ReceiveCoreCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* 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); diff --git a/src/WINNT/afsd/smb.h b/src/WINNT/afsd/smb.h index 8b45a9018..d5fa075d1 100644 --- a/src/WINNT/afsd/smb.h +++ b/src/WINNT/afsd/smb.h @@ -83,10 +83,28 @@ typedef struct smb { #define SMB_QUERY_FILE_UNIX_LINK 0x201 #define SMB_INFO_PASSTHROUGH 0x1000 +#define SMB_SET_FILE_BASIC_INFO 0x101 +#define SMB_SET_FILE_DISPOSITION_INFO 0x102 +#define SMB_SET_FILE_ALLOCATION_INFO 0x103 +#define SMB_SET_FILE_END_OF_FILE_INFO 0x104 #define SMB_SET_FILE_UNIX_BASIC 0x200 #define SMB_SET_FILE_UNIX_LINK 0x201 #define SMB_SET_FILE_UNIX_HLINK 0x203 +#define SMB_INFO_ALLOCATION 1 +#define SMB_INFO_VOLUME 2 +#define SMB_QUERY_FS_VOLUME_INFO 0x102 +#define SMB_QUERY_FS_SIZE_INFO 0x103 +#define SMB_QUERY_FS_DEVICE_INFO 0x104 +#define SMB_QUERY_FS_ATTRIBUTE_INFO 0x105 +#define SMB_INFO_UNIX 0x200 +#define SMB_INFO_MACOS 0x301 + +#define SMB_FIND_FILE_DIRECTORY_INFO 0x101 +#define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102 +#define SMB_FIND_FILE_NAMES_INFO 0x103 +#define SMB_FIND_FILE_BOTH_DIRECTORY_INFO 0x104 + /* more defines */ #define SMB_NOPCODES 256 /* # of opcodes in the dispatch table */ @@ -386,7 +404,7 @@ typedef struct smb_fid { #define SMB_FID_QLOCK_PID 0 /* - * SMB file attributes (32-bit) + * SMB file attributes (16-bit) */ #define SMB_ATTR_READONLY 0x0001 #define SMB_ATTR_HIDDEN 0x0002 /* hidden file for the purpose of dir listings */ @@ -395,6 +413,8 @@ typedef struct smb_fid { #define SMB_ATTR_DIRECTORY 0x0010 #define SMB_ATTR_ARCHIVE 0x0020 #define SMB_ATTR_DEVICE 0x0040 + +/* the following are Extended File Attributes (32-bit) */ #define SMB_ATTR_NORMAL 0x0080 /* normal file. Only valid if used alone */ #define SMB_ATTR_TEMPORARY 0x0100 #define SMB_ATTR_SPARSE_FILE 0x0200 /* used with dfs links */ @@ -403,6 +423,13 @@ typedef struct smb_fid { #define SMB_ATTR_OFFLINE 0x1000 #define SMB_ATTR_NOT_CONTENT_INDEXED 0x2000 #define SMB_ATTR_ENCRYPTED 0x4000 +#define SMB_ATTR_POSIX_SEMANTICS 0x01000000 +#define SMB_ATTR_BACKUP_SEMANTICS 0x02000000 +#define SMB_ATTR_DELETE_ON_CLOSE 0x04000000 +#define SMB_ATTR_SEQUENTIAL_SCAN 0x08000000 +#define SMB_ATTR_RANDOM_ACCESS 0x10000000 +#define SMB_ATTR_NO_BUFFERING 0x20000000 +#define SMB_ATTR_WRITE_THROUGH 0x80000000 #define LOCKING_ANDX_SHARED_LOCK 0x01 /* Read-only lock */ #define LOCKING_ANDX_OPLOCK_RELEASE 0x02 /* Oplock break notification */ diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index b739b6bf8..9ef28184d 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -2092,7 +2092,7 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) /* compute initial mode bits based on read-only flag in attributes */ initialModeBits = 0666; - if (attributes & 1) + if (attributes & SMB_ATTR_READONLY) initialModeBits &= ~0222; pathp = (char *) (&p->parmsp[14]); @@ -2438,28 +2438,38 @@ long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * smb_tran2Packet_t *outp; smb_tran2QFSInfo_t qi; int responseSize; - osi_hyper_t temp; static char FSname[6] = {'A', 0, 'F', 0, 'S', 0}; osi_Log1(smb_logp, "T2 QFSInfo type 0x%x", p->parmsp[0]); switch (p->parmsp[0]) { - case 1: responseSize = sizeof(qi.u.allocInfo); break; - case 2: responseSize = sizeof(qi.u.volumeInfo); break; - break; - case 0x102: responseSize = sizeof(qi.u.FSvolumeInfo); break; - case 0x103: responseSize = sizeof(qi.u.FSsizeInfo); break; - case 0x104: responseSize = sizeof(qi.u.FSdeviceInfo); break; - case 0x105: responseSize = sizeof(qi.u.FSattributeInfo); break; - case 0x200: /* CIFS Unix Info */ - case 0x301: /* Mac FS Info */ + case SMB_INFO_ALLOCATION: + responseSize = sizeof(qi.u.allocInfo); + break; + case SMB_INFO_VOLUME: + responseSize = sizeof(qi.u.volumeInfo); + break; + case SMB_QUERY_FS_VOLUME_INFO: + responseSize = sizeof(qi.u.FSvolumeInfo); + break; + case SMB_QUERY_FS_SIZE_INFO: + responseSize = sizeof(qi.u.FSsizeInfo); + break; + case SMB_QUERY_FS_DEVICE_INFO: + responseSize = sizeof(qi.u.FSdeviceInfo); + break; + case SMB_QUERY_FS_ATTRIBUTE_INFO: + responseSize = sizeof(qi.u.FSattributeInfo); + break; + case SMB_INFO_UNIX: /* CIFS Unix Info */ + case SMB_INFO_MACOS: /* Mac FS Info */ default: return CM_ERROR_INVAL; } outp = smb_GetTran2ResponsePacket(vcp, p, op, 0, responseSize); switch (p->parmsp[0]) { - case 1: + case SMB_INFO_ALLOCATION: /* alloc info */ qi.u.allocInfo.FSID = 0; qi.u.allocInfo.sectorsPerAllocUnit = 1; @@ -2468,7 +2478,7 @@ long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * qi.u.allocInfo.bytesPerSector = 1024; break; - case 2: + case SMB_INFO_VOLUME: /* volume info */ qi.u.volumeInfo.vsn = 1234; qi.u.volumeInfo.vnCount = 4; @@ -2477,42 +2487,42 @@ long smb_ReceiveTran2QFSInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * memcpy(qi.u.volumeInfo.label, "AFS", 4); break; - case 0x102: + case SMB_QUERY_FS_VOLUME_INFO: /* FS volume info */ - memset((char *)&qi.u.FSvolumeInfo.vct, 0, sizeof(FILETIME)); + memset((char *)&qi.u.FSvolumeInfo.vct, 0, 4); qi.u.FSvolumeInfo.vsn = 1234; qi.u.FSvolumeInfo.vnCount = 8; memcpy(qi.u.FSvolumeInfo.label, "A\0F\0S\0\0", 8); break; - case 0x103: + case SMB_QUERY_FS_SIZE_INFO: /* FS size info */ - temp.HighPart = 0; - temp.LowPart = 0x7fffffff; - qi.u.FSsizeInfo.totalAllocUnits = temp; - temp.LowPart = 0x3fffffff; - qi.u.FSsizeInfo.availAllocUnits = temp; + qi.u.FSsizeInfo.totalAllocUnits.HighPart = 0; + qi.u.FSsizeInfo.totalAllocUnits.LowPart= 0x7fffffff; + qi.u.FSsizeInfo.availAllocUnits.HighPart = 0; + qi.u.FSsizeInfo.availAllocUnits.LowPart= 0x3fffffff; qi.u.FSsizeInfo.sectorsPerAllocUnit = 1; qi.u.FSsizeInfo.bytesPerSector = 1024; break; - case 0x104: + case SMB_QUERY_FS_DEVICE_INFO: /* FS device info */ - qi.u.FSdeviceInfo.devType = 0; /* don't have a number */ + qi.u.FSdeviceInfo.devType = 0x14; /* network file system */ qi.u.FSdeviceInfo.characteristics = 0x50; /* remote, virtual */ break; - case 0x105: + case SMB_QUERY_FS_ATTRIBUTE_INFO: /* FS attribute info */ /* attributes, defined in WINNT.H: * FILE_CASE_SENSITIVE_SEARCH 0x1 * FILE_CASE_PRESERVED_NAMES 0x2 + * FILE_VOLUME_QUOTAS 0x10 * 0x4000 * If bit 0x4000 is not set, Windows 95 thinks * we can't handle long (non-8.3) names, * despite our protestations to the contrary. */ - qi.u.FSattributeInfo.attributes = 0x4003; + qi.u.FSattributeInfo.attributes = 0x4013; qi.u.FSattributeInfo.maxCompLength = 255; qi.u.FSattributeInfo.FSnameLength = 6; memcpy(qi.u.FSattributeInfo.FSname, FSname, 6); @@ -2618,7 +2628,8 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t afs_uint32 dosTime; FILETIME ft; unsigned short infoLevel; - int nbytesRequired; + smb_tran2QPathInfo_t qpi; + int responseSize; unsigned short attributes; unsigned long extAttributes; char shortName[13]; @@ -2626,8 +2637,10 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t cm_user_t *userp; cm_space_t *spacep; cm_scache_t *scp, *dscp; + smb_fid_t *fidp; + unsigned short fid; + int delonclose = 0; long code = 0; - char *op; char *pathp; char *tidPathp; char *lastComp; @@ -2635,45 +2648,39 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t cm_InitReq(&req); + fid = p->parmsp[0]; + fidp = smb_FindFID(vcp, fid, 0); + if (fidp) { + lock_ObtainMutex(&fidp->mx); + delonclose = fidp->flags & SMB_FID_DELONCLOSE; + lock_ReleaseMutex(&fidp->mx); + smb_ReleaseFID(fidp); + fidp = NULL; + } + infoLevel = p->parmsp[0]; if (infoLevel == SMB_INFO_IS_NAME_VALID) - nbytesRequired = 0; + responseSize = 0; else if (infoLevel == SMB_INFO_STANDARD) - nbytesRequired = 22; + responseSize = sizeof(qpi.u.QPstandardInfo); else if (infoLevel == SMB_INFO_QUERY_EA_SIZE) - nbytesRequired = 26; - else if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { -#ifdef COMMENT - nbytesRequired = 40; -#else - nbytesRequired = 34; -#endif - } - else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { -#ifdef COMMENT - nbytesRequired = 24; -#else - nbytesRequired = 22; -#endif - } - else if (infoLevel == SMB_QUERY_FILE_EA_INFO) - nbytesRequired = 4; -#if 0 + responseSize = sizeof(qpi.u.QPeaSizeInfo); + else if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) + responseSize = sizeof(qpi.u.QPfileBasicInfo); + else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) + responseSize = sizeof(qpi.u.QPfileStandardInfo); + else if (infoLevel == SMB_QUERY_FILE_EA_INFO) + responseSize = sizeof(qpi.u.QPfileEaInfo); else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) - nbytesRequired = ???; + responseSize = sizeof(qpi.u.QPfileNameInfo); else if (infoLevel == SMB_QUERY_FILE_ALL_INFO) - nbytesRequired = ???; -#endif + responseSize = sizeof(qpi.u.QPfileAllInfo); else if (infoLevel == SMB_QUERY_FILE_ALT_NAME_INFO) - nbytesRequired = 30; + responseSize = sizeof(qpi.u.QPfileAltNameInfo); else { osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); -#ifdef COMMENT - smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); -#else smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADOP); -#endif return 0; } @@ -2683,13 +2690,13 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t osi_Log2(smb_logp, "T2 QPathInfo type 0x%x path %s", infoLevel, osi_LogSaveString(smb_logp, pathp)); - outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired); + outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, responseSize); if (infoLevel > 0x100) outp->totalParms = 2; else outp->totalParms = 0; - outp->totalData = nbytesRequired; + outp->totalData = responseSize; /* now, if we're at infoLevel 6, we're only being asked to check * the syntax, so we just OK things now. In particular, we're *not* @@ -2809,9 +2816,8 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* now we have the status in the cache entry, and everything is locked. * Marshall the output data. */ - op = outp->datap; /* for info level 108, figure out short name */ - if (infoLevel == 0x108) { + if (infoLevel == SMB_QUERY_FILE_ALT_NAME_INFO) { code = cm_GetShortName(pathp, userp, &req, tidPathp, scp->fid.vnode, shortName, (size_t *) &len); @@ -2819,80 +2825,230 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t goto done; } - op = outp->datap; - *((u_long *)op) = len * 2; op += 4; - mbstowcs((unsigned short *)op, shortName, len); - op += (len * 2); + qpi.u.QPfileAltNameInfo.fileNameLength = len * 2; + mbstowcs((unsigned short *)qpi.u.QPfileAltNameInfo.fileName, shortName, len); goto done; } - if (infoLevel == SMB_INFO_STANDARD || infoLevel == SMB_INFO_QUERY_EA_SIZE) { + else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) { + len = strlen(lastComp); + qpi.u.QPfileNameInfo.fileNameLength = len * 2; + mbstowcs((unsigned short *)qpi.u.QPfileNameInfo.fileName, lastComp, len); + + goto done; + } + else if (infoLevel == SMB_INFO_STANDARD || infoLevel == SMB_INFO_QUERY_EA_SIZE) { smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime); - *((u_long *)op) = dosTime; op += 4; /* creation time */ - *((u_long *)op) = dosTime; op += 4; /* access time */ - *((u_long *)op) = dosTime; op += 4; /* write time */ - *((u_long *)op) = scp->length.LowPart; op += 4; /* length */ - *((u_long *)op) = scp->length.LowPart; op += 4; /* alloc size */ + qpi.u.QPstandardInfo.creationDateTime = dosTime; + qpi.u.QPstandardInfo.lastAccessDateTime = dosTime; + qpi.u.QPstandardInfo.lastWriteDateTime = dosTime; + qpi.u.QPstandardInfo.dataSize = scp->length.LowPart; + qpi.u.QPstandardInfo.allocationSize = scp->length.LowPart; attributes = smb_Attributes(scp); - *((u_short *)op) = attributes; op += 2; /* attributes */ - - /* now, if we are being asked about extended attrs, return a 0 size */ - if (infoLevel == SMB_INFO_QUERY_EA_SIZE) { - *((u_long *)op) = 0; op += 4; - } + qpi.u.QPstandardInfo.attributes = attributes; + qpi.u.QPstandardInfo.eaSize = 0; } else if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); - *((FILETIME *)op) = ft; op += 8; /* creation time */ - *((FILETIME *)op) = ft; op += 8; /* last access time */ - *((FILETIME *)op) = ft; op += 8; /* last write time */ - *((FILETIME *)op) = ft; op += 8; /* last change time */ + qpi.u.QPfileBasicInfo.creationTime = ft; + qpi.u.QPfileBasicInfo.lastAccessTime = ft; + qpi.u.QPfileBasicInfo.lastWriteTime = ft; + qpi.u.QPfileBasicInfo.changeTime = ft; extAttributes = smb_ExtAttributes(scp); -#ifdef COMMENT - *((u_long *)op) = extAttributes; op += 4; /* extended attribs */ - *((u_long *)op) = 0; op += 4; /* don't know what this is */ -#else - /* The CIFS Specs say */ - *((u_short *)op) = extAttributes; op += 2; /* extended attributes */ -#endif + qpi.u.QPfileBasicInfo.attributes = extAttributes; } else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { - *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */ - *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */ - *((u_long *)op) = scp->linkCount; op += 4; /* Link count */ - *op++ = 0; /* Delete Pending */ - *op++ = ((scp->fileType == CM_SCACHETYPE_DIRECTORY || - scp->fileType == CM_SCACHETYPE_MOUNTPOINT || - scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); -#ifdef COMMENT - *op++ = 0; - *op++ = 0; -#endif + qpi.u.QPfileStandardInfo.allocationSize = scp->length; + qpi.u.QPfileStandardInfo.endOfFile = scp->length; + qpi.u.QPfileStandardInfo.numberOfLinks = scp->linkCount; + qpi.u.QPfileStandardInfo.deletePending = (delonclose ? 1 : 0); + qpi.u.QPfileStandardInfo.directory = + ((scp->fileType == CM_SCACHETYPE_DIRECTORY || + scp->fileType == CM_SCACHETYPE_MOUNTPOINT || + scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); } else if (infoLevel == SMB_QUERY_FILE_EA_INFO) { - memset(op, 0, 4); op += 4; /* EA size */ + qpi.u.QPfileEaInfo.eaSize = 0; + } + else if (infoLevel == SMB_QUERY_FILE_ALL_INFO) { + smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); + qpi.u.QPfileAllInfo.creationTime = ft; + qpi.u.QPfileAllInfo.lastAccessTime = ft; + qpi.u.QPfileAllInfo.lastWriteTime = ft; + qpi.u.QPfileAllInfo.changeTime = ft; + extAttributes = smb_ExtAttributes(scp); + qpi.u.QPfileAllInfo.attributes = extAttributes; + qpi.u.QPfileAllInfo.allocationSize = scp->length; + qpi.u.QPfileAllInfo.endOfFile = scp->length; + qpi.u.QPfileAllInfo.numberOfLinks = scp->linkCount; + qpi.u.QPfileAllInfo.deletePending = 0; + qpi.u.QPfileAllInfo.directory = + ((scp->fileType == CM_SCACHETYPE_DIRECTORY || + scp->fileType == CM_SCACHETYPE_MOUNTPOINT || + scp->fileType == CM_SCACHETYPE_INVALID) ? 1 : 0); + qpi.u.QPfileAllInfo.indexNumber.HighPart = scp->fid.cell; + qpi.u.QPfileAllInfo.indexNumber.LowPart = scp->fid.volume; + qpi.u.QPfileAllInfo.eaSize = 0; + qpi.u.QPfileAllInfo.accessFlags = 0; + qpi.u.QPfileAllInfo.indexNumber2.HighPart = scp->fid.vnode; + qpi.u.QPfileAllInfo.indexNumber2.LowPart = scp->fid.unique; + qpi.u.QPfileAllInfo.currentByteOffset.HighPart = 0; + qpi.u.QPfileAllInfo.currentByteOffset.LowPart = 0; + qpi.u.QPfileAllInfo.mode = 0; + qpi.u.QPfileAllInfo.alignmentRequirement = 0; + len = strlen(lastComp); + qpi.u.QPfileAllInfo.fileNameLength = len * 2; + mbstowcs((unsigned short *)qpi.u.QPfileAllInfo.fileName, lastComp, len); } - - /* send and free the packets */ done: lock_ReleaseMutex(&scp->mx); cm_ReleaseSCache(scp); cm_ReleaseUser(userp); - if (code == 0) - smb_SendTran2Packet(vcp, outp, opx); - else + if (code == 0) { + memcpy(outp->datap, &qpi, responseSize); + smb_SendTran2Packet(vcp, outp, opx); + } else { smb_SendTran2Error(vcp, p, opx, code); + } smb_FreeTran2Packet(outp); return 0; } -long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *outp) +long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { +#if 0 osi_Log0(smb_logp,"ReceiveTran2SetPathInfo - NOT_SUPPORTED"); return CM_ERROR_BADOP; +#else + long code = 0; + unsigned short fid; + smb_fid_t *fidp; + unsigned short infoLevel; + smb_tran2Packet_t *outp; + smb_tran2QPathInfo_t *spi; + cm_user_t *userp; + cm_scache_t *scp; + cm_req_t req; + + cm_InitReq(&req); + + fid = p->parmsp[0]; + fidp = smb_FindFID(vcp, fid, 0); + + if (fidp == NULL) { + smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADFD); + return 0; + } + + infoLevel = p->parmsp[1]; + osi_Log2(smb_logp,"ReceiveTran2SetPathInfo type 0x%x fid %d", infoLevel, fid); + if (infoLevel != SMB_INFO_STANDARD && + infoLevel != SMB_INFO_QUERY_EA_SIZE && + infoLevel != SMB_INFO_QUERY_ALL_EAS) { + osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", + p->opcode, infoLevel); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); + smb_ReleaseFID(fidp); + return 0; + } + + lock_ObtainMutex(&fidp->mx); + if (!(fidp->flags & SMB_FID_OPENWRITE)) { + lock_ReleaseMutex(&fidp->mx); + smb_ReleaseFID(fidp); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); + return 0; + } + + scp = fidp->scp; + cm_HoldSCache(scp); + lock_ReleaseMutex(&fidp->mx); + + outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, 0); + + outp->totalParms = 2; + outp->totalData = 0; + + userp = smb_GetTran2User(vcp, p); + if (!userp) { + osi_Log1(smb_logp,"ReceiveTran2SetPathInfo unable to resolve user [%d]", p->uid); + code = CM_ERROR_BADSMB; + goto done; + } + + spi = (smb_tran2QPathInfo_t *)p->datap; + if (infoLevel == SMB_INFO_STANDARD || infoLevel == SMB_INFO_QUERY_EA_SIZE) { + cm_attr_t attr; + + /* lock the vnode with a callback; we need the current status + * to determine what the new status is, in some cases. + */ + lock_ObtainMutex(&scp->mx); + code = cm_SyncOp(scp, NULL, userp, &req, 0, + CM_SCACHESYNC_GETSTATUS + | CM_SCACHESYNC_NEEDCALLBACK); + lock_ReleaseMutex(&scp->mx); + if (code) { + goto done; + } + + lock_ObtainMutex(&fidp->mx); + lock_ObtainMutex(&scp->mx); + + /* prepare for setattr call */ + attr.mask = CM_ATTRMASK_LENGTH; + attr.length.LowPart = spi->u.QPstandardInfo.dataSize; + attr.length.HighPart = 0; + + if (spi->u.QPstandardInfo.lastWriteDateTime != 0) { + smb_UnixTimeFromSearchTime(&attr.clientModTime, spi->u.QPstandardInfo.lastWriteDateTime); + attr.mask |= CM_ATTRMASK_CLIENTMODTIME; + fidp->flags |= SMB_FID_MTIMESETDONE; + } + + if (spi->u.QPstandardInfo.attributes != 0) { + if ((scp->unixModeBits & 0222) + && (spi->u.QPstandardInfo.attributes & SMB_ATTR_READONLY) != 0) { + /* make a writable file read-only */ + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + attr.unixModeBits = scp->unixModeBits & ~0222; + } + else if ((scp->unixModeBits & 0222) == 0 + && (spi->u.QPstandardInfo.attributes & SMB_ATTR_READONLY) == 0) { + /* make a read-only file writable */ + attr.mask |= CM_ATTRMASK_UNIXMODEBITS; + attr.unixModeBits = scp->unixModeBits | 0222; + } + } + lock_ReleaseMutex(&scp->mx); + lock_ReleaseMutex(&fidp->mx); + + /* call setattr */ + if (attr.mask) + code = cm_SetAttr(scp, &attr, userp, &req); + else + code = 0; + } + else if (infoLevel == SMB_INFO_QUERY_ALL_EAS) { + /* we don't support EAs */ + code = CM_ERROR_INVAL; + } + + done: + cm_ReleaseSCache(scp); + cm_ReleaseUser(userp); + smb_ReleaseFID(fidp); + if (code == 0) + smb_SendTran2Packet(vcp, outp, opx); + else + smb_SendTran2Error(vcp, p, opx, code); + smb_FreeTran2Packet(outp); + + return 0; +#endif } long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) @@ -2901,13 +3057,13 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t FILETIME ft; unsigned long attributes; unsigned short infoLevel; - int nbytesRequired; + int responseSize; unsigned short fid; int delonclose = 0; cm_user_t *userp; smb_fid_t *fidp; cm_scache_t *scp; - char *op; + smb_tran2QFileInfo_t qfi; long code = 0; cm_req_t req; @@ -2923,13 +3079,13 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t infoLevel = p->parmsp[1]; if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) - nbytesRequired = 40; + responseSize = sizeof(qfi.u.QFbasicInfo); else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) - nbytesRequired = 24; + responseSize = sizeof(qfi.u.QFstandardInfo); else if (infoLevel == SMB_QUERY_FILE_EA_INFO) - nbytesRequired = 4; + responseSize = sizeof(qfi.u.QFeaInfo); else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) - nbytesRequired = 6; + responseSize = sizeof(qfi.u.QFfileNameInfo); else { osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); @@ -2939,13 +3095,13 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t } osi_Log2(smb_logp, "T2 QFileInfo type 0x%x fid %d", infoLevel, fid); - outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, nbytesRequired); + outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, responseSize); if (infoLevel > 0x100) outp->totalParms = 2; else outp->totalParms = 0; - outp->totalData = nbytesRequired; + outp->totalData = responseSize; userp = smb_GetTran2User(vcp, p); if (!userp) { @@ -2968,30 +3124,27 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* now we have the status in the cache entry, and everything is locked. * Marshall the output data. */ - op = outp->datap; if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); - *((FILETIME *)op) = ft; op += 8; /* creation time */ - *((FILETIME *)op) = ft; op += 8; /* last access time */ - *((FILETIME *)op) = ft; op += 8; /* last write time */ - *((FILETIME *)op) = ft; op += 8; /* last change time */ + qfi.u.QFbasicInfo.creationTime = ft; + qfi.u.QFbasicInfo.lastAccessTime = ft; + qfi.u.QFbasicInfo.lastWriteTime = ft; + qfi.u.QFbasicInfo.lastChangeTime = ft; attributes = smb_ExtAttributes(scp); - *((u_long *)op) = attributes; op += 4; - *((u_long *)op) = 0; op += 4; + qfi.u.QFbasicInfo.attributes = attributes; } else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { - *((LARGE_INTEGER *)op) = scp->length; op += 8; /* alloc size */ - *((LARGE_INTEGER *)op) = scp->length; op += 8; /* EOF */ - *((u_long *)op) = scp->linkCount; op += 4; /* Link count */ - *op++ = (delonclose ? 1 : 0); /* Delete Pending */ - *op++ = ((scp->fileType == CM_SCACHETYPE_DIRECTORY || - scp->fileType == CM_SCACHETYPE_MOUNTPOINT || - scp->fileType == CM_SCACHETYPE_INVALID)? 1 : 0); - *op++ = 0; - *op++ = 0; + qfi.u.QFstandardInfo.allocationSize = scp->length; + qfi.u.QFstandardInfo.endOfFile = scp->length; + qfi.u.QFstandardInfo.numberOfLinks = scp->linkCount; + qfi.u.QFstandardInfo.deletePending = (delonclose ? 1 : 0); + qfi.u.QFstandardInfo.directory = + ((scp->fileType == CM_SCACHETYPE_DIRECTORY || + scp->fileType == CM_SCACHETYPE_MOUNTPOINT || + scp->fileType == CM_SCACHETYPE_INVALID)? 1 : 0); } else if (infoLevel == SMB_QUERY_FILE_EA_INFO) { - *((u_long *)op) = 0; op += 4; + qfi.u.QFeaInfo.eaSize = 0; } else if (infoLevel == SMB_QUERY_FILE_NAME_INFO) { unsigned long len; @@ -3007,8 +3160,8 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t lock_ReleaseMutex(&fidp->mx); len = (unsigned long)strlen(name); outp->totalData = (len*2) + 4; /* this is actually what we want to return */ - *((u_long *)op) = len * 2; op += 4; - mbstowcs((unsigned short *)op, name, len); op += (len * 2); + qfi.u.QFfileNameInfo.fileNameLength = len * 2; + mbstowcs((unsigned short *)qfi.u.QFfileNameInfo.fileName, name, len); } /* send and free the packets */ @@ -3017,16 +3170,18 @@ long smb_ReceiveTran2QFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t cm_ReleaseSCache(scp); cm_ReleaseUser(userp); smb_ReleaseFID(fidp); - if (code == 0) + if (code == 0) { + memcpy(outp->datap, &qfi, responseSize); smb_SendTran2Packet(vcp, outp, opx); - else + } else { smb_SendTran2Error(vcp, p, opx, code); + } smb_FreeTran2Packet(outp); return 0; } -long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) +long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *opx) { long code = 0; unsigned short fid; @@ -3043,32 +3198,33 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet fidp = smb_FindFID(vcp, fid, 0); if (fidp == NULL) { - smb_SendTran2Error(vcp, p, op, CM_ERROR_BADFD); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_BADFD); return 0; } infoLevel = p->parmsp[1]; osi_Log2(smb_logp,"ReceiveTran2SetFileInfo type 0x%x fid %d", infoLevel, fid); - if (infoLevel > 0x104 || infoLevel < 0x101) { + if (infoLevel > SMB_SET_FILE_END_OF_FILE_INFO || infoLevel < SMB_SET_FILE_BASIC_INFO) { osi_Log2(smb_logp, "Bad Tran2 op 0x%x infolevel 0x%x", p->opcode, infoLevel); - smb_SendTran2Error(vcp, p, op, CM_ERROR_INVAL); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_INVAL); smb_ReleaseFID(fidp); return 0; } lock_ObtainMutex(&fidp->mx); - if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO && !(fidp->flags & SMB_FID_OPENDELETE)) { + if (infoLevel == SMB_SET_FILE_DISPOSITION_INFO && !(fidp->flags & SMB_FID_OPENDELETE)) { lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); - smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); return 0; } - if ((infoLevel == SMB_QUERY_FILE_EA_INFO || infoLevel == SMB_QUERY_FILE_NAME_INFO) + if ((infoLevel == SMB_SET_FILE_ALLOCATION_INFO || + infoLevel == SMB_SET_FILE_END_OF_FILE_INFO) && !(fidp->flags & SMB_FID_OPENWRITE)) { lock_ReleaseMutex(&fidp->mx); smb_ReleaseFID(fidp); - smb_SendTran2Error(vcp, p, op, CM_ERROR_NOACCESS); + smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOACCESS); return 0; } @@ -3076,9 +3232,7 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet cm_HoldSCache(scp); lock_ReleaseMutex(&fidp->mx); - osi_Log1(smb_logp, "T2 SFileInfo type 0x%x", infoLevel); - - outp = smb_GetTran2ResponsePacket(vcp, p, op, 2, 0); + outp = smb_GetTran2ResponsePacket(vcp, p, opx, 2, 0); outp->totalParms = 2; outp->totalData = 0; @@ -3090,12 +3244,15 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet goto done; } - if (infoLevel == SMB_QUERY_FILE_BASIC_INFO) { + if (infoLevel == SMB_SET_FILE_BASIC_INFO) { FILETIME lastMod; unsigned int attribute; cm_attr_t attr; + smb_tran2QFileInfo_t *sfi; - /* lock the vnode with a callback; we need the current status + sfi = (smb_tran2QFileInfo_t *)p->datap; + + /* lock the vnode with a callback; we need the current status * to determine what the new status is, in some cases. */ lock_ObtainMutex(&scp->mx); @@ -3103,9 +3260,8 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet CM_SCACHESYNC_GETSTATUS | CM_SCACHESYNC_NEEDCALLBACK); lock_ReleaseMutex(&scp->mx); - if (code) { + if (code) goto done; - } lock_ObtainMutex(&fidp->mx); lock_ObtainMutex(&scp->mx); @@ -3113,7 +3269,7 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet /* prepare for setattr call */ attr.mask = 0; - lastMod = *((FILETIME *)(p->datap + 16)); + lastMod = sfi->u.QFbasicInfo.lastWriteTime; /* when called as result of move a b, lastMod is (-1, -1). * If the check for -1 is not present, timestamp * of the resulting file will be 1969 (-1) @@ -3125,16 +3281,16 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet fidp->flags |= SMB_FID_MTIMESETDONE; } - attribute = *((u_long *)(p->datap + 32)); + attribute = sfi->u.QFbasicInfo.attributes; if (attribute != 0) { if ((scp->unixModeBits & 0222) - && (attribute & 1) != 0) { + && (attribute & SMB_ATTR_READONLY) != 0) { /* make a writable file read-only */ attr.mask |= CM_ATTRMASK_UNIXMODEBITS; attr.unixModeBits = scp->unixModeBits & ~0222; } else if ((scp->unixModeBits & 0222) == 0 - && (attribute & 1) == 0) { + && (attribute & SMB_ATTR_READONLY) == 0) { /* make a read-only file writable */ attr.mask |= CM_ATTRMASK_UNIXMODEBITS; attr.unixModeBits = scp->unixModeBits | 0222; @@ -3148,18 +3304,9 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet code = cm_SetAttr(scp, &attr, userp, &req); else code = 0; - } - else if (infoLevel == SMB_QUERY_FILE_EA_INFO || infoLevel == SMB_QUERY_FILE_NAME_INFO) { - LARGE_INTEGER size = *((LARGE_INTEGER *)(p->datap)); - cm_attr_t attr; - - attr.mask = CM_ATTRMASK_LENGTH; - attr.length.LowPart = size.LowPart; - attr.length.HighPart = size.HighPart; - code = cm_SetAttr(scp, &attr, userp, &req); - } - else if (infoLevel == SMB_QUERY_FILE_STANDARD_INFO) { - if (*((char *)(p->datap))) { + } + else if (infoLevel == SMB_SET_FILE_DISPOSITION_INFO) { + if (*((char *)(p->datap))) { /* File is Deleted */ code = cm_CheckNTDelete(fidp->NTopen_dscp, scp, userp, &req); if (code == 0) { @@ -3175,15 +3322,32 @@ long smb_ReceiveTran2SetFileInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet lock_ReleaseMutex(&fidp->mx); } } + else if (infoLevel == SMB_SET_FILE_ALLOCATION_INFO) { + LARGE_INTEGER size = *((LARGE_INTEGER *)(p->datap)); + cm_attr_t attr; + + attr.mask = CM_ATTRMASK_LENGTH; + attr.length.LowPart = size.LowPart; + attr.length.HighPart = size.HighPart; + code = cm_SetAttr(scp, &attr, userp, &req); + } + else if (infoLevel == SMB_SET_FILE_END_OF_FILE_INFO) { + unsigned short size = *((unsigned short *)(p->datap)); + cm_attr_t attr; + + attr.mask = CM_ATTRMASK_LENGTH; + attr.length.LowPart = size; + code = cm_SetAttr(scp, &attr, userp, &req); + } done: cm_ReleaseSCache(scp); cm_ReleaseUser(userp); smb_ReleaseFID(fidp); if (code == 0) - smb_SendTran2Packet(vcp, outp, op); + smb_SendTran2Packet(vcp, outp, opx); else - smb_SendTran2Error(vcp, p, op, code); + smb_SendTran2Error(vcp, p, opx, code); smb_FreeTran2Packet(outp); return 0; @@ -3393,7 +3557,7 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, /* Plug in fake timestamps. A time stamp of 0 causes 'invalid parameter' errors in the client. */ - if (infoLevel >= 0x101) { + if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) { /* 1969-12-31 23:59:59 +00 */ ft.dwHighDateTime = 0x19DB200; ft.dwLowDateTime = 0x5BB78980; @@ -3483,7 +3647,7 @@ smb_ApplyV3DirListPatches(cm_scache_t *dscp, dptr = patchp->dptr; - if (infoLevel >= 0x101) { + if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) { /* get filetime */ smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime); @@ -3912,6 +4076,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t int fileType; cm_fid_t fid; cm_req_t req; + char * s; cm_InitReq(&req); @@ -3956,14 +4121,42 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t starPattern = 1; /* assume, since required a Find Next */ } + switch ( infoLevel ) { + case SMB_INFO_STANDARD: + s = "InfoStandard"; + break; + case SMB_INFO_QUERY_EA_SIZE: + s = "InfoQueryEaSize"; + break; + case SMB_INFO_QUERY_EAS_FROM_LIST: + s = "InfoQueryEasFromList"; + break; + case SMB_FIND_FILE_DIRECTORY_INFO: + s = "FindFileDirectoryInfo"; + break; + case SMB_FIND_FILE_FULL_DIRECTORY_INFO: + s = "FindFileFullDirectoryInfo"; + break; + case SMB_FIND_FILE_NAMES_INFO: + s = "FindFileNamesInfo"; + break; + case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: + s = "FindFileBothDirectoryInfo"; + break; + default: + s = "unknownInfoLevel"; + } + + osi_Log1(smb_logp, "T2 search dir info level: %s", s); + osi_Log4(smb_logp, - "T2 search dir attr 0x%x, info level %d, max count %d, flags 0x%x", + "T2 search dir attr 0x%x, info level 0x%x, max count %d, flags 0x%x", attribute, infoLevel, maxCount, searchFlags); osi_Log3(smb_logp, "...T2 search op %d, id %d, nextCookie 0x%x", p->opcode, dsp->cookie, nextCookie); - if (infoLevel >= 0x101) + if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) searchFlags &= ~4; /* no resume keys */ dirListPatchesp = NULL; @@ -4267,7 +4460,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* Need 8.3 name? */ NeedShortName = 0; - if (infoLevel == SMB_QUERY_FILE_NAME_INFO + if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO && dep->fid.vnode != 0 && !cm_Is8Dot3(dep->name)) { cm_Gen8Dot3Name(dep, shortName, &shortNameEnd); @@ -4316,21 +4509,21 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* standard dir entry stuff */ if (infoLevel < 0x101) ohbytes = 23; /* pre-NT */ - else if (infoLevel == SMB_QUERY_FILE_EA_INFO) + else if (infoLevel == SMB_FIND_FILE_NAMES_INFO) ohbytes = 12; /* NT names only */ else ohbytes = 64; /* NT */ - if (infoLevel == SMB_QUERY_FILE_NAME_INFO) + if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) ohbytes += 26; /* Short name & length */ if (searchFlags & 4) { ohbytes += 4; /* if resume key required */ } - if (infoLevel != 1 - && infoLevel != 0x101 - && infoLevel != 0x103) + if (infoLevel != SMB_INFO_STANDARD + && infoLevel != SMB_FIND_FILE_DIRECTORY_INFO + && infoLevel != SMB_FIND_FILE_NAMES_INFO) ohbytes += 4; /* EASIZE */ /* add header to name & term. null */ @@ -4342,7 +4535,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * about an * overflow when we pad things out below). * That's the reason for the alignment arithmetic below. */ - if (infoLevel >= 0x101) + if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) align = (4 - (orbytes & 3)) & 3; else align = 0; @@ -4359,9 +4552,9 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t /* First zero everything else */ memset(origOp, 0, ohbytes); - if (infoLevel <= 0x101) + if (infoLevel <= SMB_FIND_FILE_DIRECTORY_INFO) *(origOp + ohbytes - 1) = (unsigned char) onbytes; - else if (infoLevel == SMB_QUERY_FILE_EA_INFO) + else if (infoLevel == SMB_FIND_FILE_NAMES_INFO) *((u_long *)(op + 8)) = onbytes; else *((u_long *)(op + 60)) = onbytes; @@ -4370,7 +4563,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t CharToOem(origOp+ohbytes, origOp+ohbytes); /* Short name if requested and needed */ - if (infoLevel == SMB_QUERY_FILE_NAME_INFO) { + if (infoLevel == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) { if (NeedShortName) { strcpy(op + 70, shortName); if (smb_StoreAnsiFilenames) @@ -4383,7 +4576,7 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t returnedNames++; /* NextEntryOffset and FileIndex */ - if (infoLevel >= 101) { + if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) { int entryOffset = orbytes + align; *((u_long *)op) = entryOffset; *((u_long *)(op+4)) = nextEntryCookie; @@ -4402,12 +4595,12 @@ long smb_ReceiveTran2SearchDir(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t * later. The replay will happen at a time when it is * safe to unlock the directory. */ - if (infoLevel != 0x103) { + if (infoLevel != SMB_FIND_FILE_NAMES_INFO) { curPatchp = malloc(sizeof(*curPatchp)); osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q); curPatchp->dptr = op; - if (infoLevel >= 0x101) + if (infoLevel >= SMB_FIND_FILE_DIRECTORY_INFO) curPatchp->dptr += 8; if (smb_hideDotFiles && smb_IsDotFile(dep->name)) { @@ -4603,7 +4796,8 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* 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; pathp = smb_GetSMBData(inp, NULL); if (smb_StoreAnsiFilenames) @@ -6437,7 +6631,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out * extended attributes */ initialModeBits = 0666; - if (extAttributes & 1) + if (extAttributes & SMB_ATTR_READONLY) initialModeBits &= ~0222; pathp = parmp + (13 * sizeof(ULONG)) + sizeof(UCHAR); diff --git a/src/WINNT/afsd/smb3.h b/src/WINNT/afsd/smb3.h index 6a6caa987..b6e86b7c9 100644 --- a/src/WINNT/afsd/smb3.h +++ b/src/WINNT/afsd/smb3.h @@ -52,20 +52,20 @@ typedef struct smb_tran2QFSInfo { } allocInfo; #pragma pack(pop) struct { - unsigned long vsn; /* volume serial number */ - char vnCount; /* count of chars in label, incl null */ - char label[12]; /* pad out with nulls */ + unsigned long vsn; /* volume serial number */ + char vnCount; /* count of chars in label, incl null */ + char label[12]; /* pad out with nulls */ } volumeInfo; struct { - FILETIME vct; /* volume creation time */ + FILETIME vct; /* volume creation time */ unsigned long vsn; /* volume serial number */ unsigned long vnCount; /* length of volume label in bytes */ char res[2]; /* reserved */ char label[10]; /* volume label */ } FSvolumeInfo; struct { - osi_hyper_t totalAllocUnits; /* on the disk */ - osi_hyper_t availAllocUnits; /* free blocks */ + LARGE_INTEGER totalAllocUnits; /* on the disk */ + LARGE_INTEGER availAllocUnits; /* free blocks */ unsigned long sectorsPerAllocUnit; unsigned long bytesPerSector; /* bytes per sector */ } FSsizeInfo; @@ -82,6 +82,128 @@ typedef struct smb_tran2QFSInfo { } u; } smb_tran2QFSInfo_t; +typedef struct { + union { + struct { + unsigned long creationDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long lastAccessDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long lastWriteDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long dataSize; + unsigned long allocationSize; + unsigned short attributes; + unsigned long eaSize; + } QPstandardInfo; + struct { + unsigned long creationDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long lastAccessDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long lastWriteDateTime; /* SMB_DATE / SMB_TIME */ + unsigned long dataSize; + unsigned long allocationSize; + unsigned short attributes; + unsigned long eaSize; + } QPeaSizeInfo; + struct { + unsigned short maxDataCount; + unsigned short eaErrorOffset; + unsigned long listLength; + unsigned char eaList[128]; + } QPeasFromListInfo; + struct { + unsigned short maxDataCount; + unsigned short eaErrorOffset; + unsigned long listLength; + unsigned char eaList[128]; + } QPallEasInfo; + struct { + FILETIME creationTime; + FILETIME lastAccessTime; + FILETIME lastWriteTime; + FILETIME changeTime; + unsigned short attributes; + } QPfileBasicInfo; + struct { + LARGE_INTEGER allocationSize; + LARGE_INTEGER endOfFile; + unsigned long numberOfLinks; + unsigned char deletePending; + unsigned char directory; + } QPfileStandardInfo; + struct { + unsigned long eaSize; + } QPfileEaInfo; + struct { + unsigned long fileNameLength; + unsigned char fileName[512]; + } QPfileNameInfo; + struct { + FILETIME creationTime; + FILETIME lastAccessTime; + FILETIME lastWriteTime; + FILETIME changeTime; + unsigned short attributes; + LARGE_INTEGER allocationSize; + LARGE_INTEGER endOfFile; + unsigned long numberOfLinks; + unsigned char deletePending; + unsigned char directory; + LARGE_INTEGER indexNumber; + unsigned long eaSize; + unsigned long accessFlags; + LARGE_INTEGER indexNumber2; + LARGE_INTEGER currentByteOffset; + unsigned long mode; + unsigned long alignmentRequirement; + unsigned long fileNameLength; + unsigned char fileName[512]; + } QPfileAllInfo; + struct { + unsigned long fileNameLength; + unsigned char fileName[512]; + } QPfileAltNameInfo; + struct { + unsigned long nextEntryOffset; + unsigned long streamNameLength; + LARGE_INTEGER streamSize; + LARGE_INTEGER streamAllocationSize; + unsigned char fileName[512]; + } QPfileStreamInfo; + struct { + LARGE_INTEGER compressedFileSize; + unsigned short compressionFormat; + unsigned char compressionUnitShift; + unsigned char chuckShift; + unsigned char clusterShift; + unsigned char reserved[3]; + } QPfileCompressionInfo; + } u; +} smb_tran2QPathInfo_t; + +typedef struct { + union { + struct { + FILETIME creationTime; + FILETIME lastAccessTime; + FILETIME lastWriteTime; + FILETIME lastChangeTime; + unsigned short attributes; + } QFbasicInfo; + struct { + LARGE_INTEGER allocationSize; + LARGE_INTEGER endOfFile; + unsigned long numberOfLinks; + unsigned char deletePending; + unsigned char directory; + } QFstandardInfo; + struct { + unsigned long eaSize; + } QFeaInfo; + struct { + unsigned long fileNameLength; + unsigned char fileName[512]; + } QFfileNameInfo; + } u; +} smb_tran2QFileInfo_t; + /* more than enough opcodes for today, anyway */ #define SMB_TRAN2_NOPCODES 20 -- 2.39.5