]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
windows-cifs-rewrite-20060717
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 17 Jul 2006 19:45:27 +0000 (19:45 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 17 Jul 2006 19:45:27 +0000 (19:45 +0000)
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
src/WINNT/afsd/smb.h
src/WINNT/afsd/smb3.c
src/WINNT/afsd/smb3.h

index 831f1bd4204ee685486f7e124333b25e2375e8e6..7252340510cb0ea4073a8f342e64b57ecf84ff83 100644 (file)
@@ -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);
index 8b45a90187e0ded23c2eaab83f26ab88abfc11cc..d5fa075d107b0d27d29c8fa68f1e01aa2e28d134 100644 (file)
@@ -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 */
index b739b6bf8850f3516efdaebc220a05abfe5ae10a..9ef28184d5cc165a9c31d33f834ea686794f563c 100644 (file)
@@ -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
          *     <no name defined>               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);
index 6a6caa9875f455b8cfe997813d715f965c73c257..b6e86b7c9314e1147608dabe0027d588eb9d6ff5 100644 (file)
@@ -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