DEVEL15-windows-largefile-support-20060623
[openafs.git] / src / WINNT / afsd / smb_ioctl.c
index 2bfebde..70f4b28 100644 (file)
@@ -31,6 +31,10 @@ smb_ioctlProc_t *smb_ioctlProcsp[SMB_IOCTL_MAXPROCS];
 
 void smb_InitIoctl(void)
 {
+        int i;
+        for (i=0; i<SMB_IOCTL_MAXPROCS; i++)
+           smb_ioctlProcsp[i] = NULL;
+
        smb_ioctlProcsp[VIOCGETAL] = cm_IoctlGetACL;
         smb_ioctlProcsp[VIOC_FILE_CELL_NAME] = cm_IoctlGetFileCellName;
         smb_ioctlProcsp[VIOCSETAL] = cm_IoctlSetACL;
@@ -74,6 +78,11 @@ void smb_InitIoctl(void)
 #endif
        smb_ioctlProcsp[VIOC_TRACEMEMDUMP] = cm_IoctlMemoryDump;
        smb_ioctlProcsp[VIOC_ISSYMLINK] = cm_IoctlIslink;
+        smb_ioctlProcsp[VIOC_FLUSHALL] = cm_IoctlFlushAllVolumes;
+        smb_ioctlProcsp[VIOCGETFID] = cm_IoctlGetFid;
+        smb_ioctlProcsp[VIOCGETOWNER] = cm_IoctlGetOwner;
+        smb_ioctlProcsp[VIOC_RXSTAT_PROC] = cm_IoctlRxStatProcess;
+        smb_ioctlProcsp[VIOC_RXSTAT_PEER] = cm_IoctlRxStatPeer;
 }
 
 /* called to make a fid structure into an IOCTL fid structure */
@@ -107,7 +116,7 @@ void smb_SetupIoctlFid(smb_fid_t *fidp, cm_space_t *prefix)
 smb_IoctlPrepareRead(smb_fid_t *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp)
 {
     long opcode;
-    smb_ioctlProc_t *procp;
+    smb_ioctlProc_t *procp = NULL;
     long code;
 
     if (ioctlp->flags & SMB_IOCTLFLAG_DATAIN) {
@@ -128,7 +137,11 @@ smb_IoctlPrepareRead(smb_fid_t *fidp, smb_ioctl_t *ioctlp, cm_user_t *userp)
             return CM_ERROR_TOOBIG;
 
         /* check for no such proc */
-        procp = smb_ioctlProcsp[opcode];
+       if (fidp->flags & SMB_FID_IOCTL)
+           procp = smb_ioctlProcsp[opcode];
+       else
+           procp = NULL;
+
         if (procp == NULL) 
             return CM_ERROR_BADOP;
 
@@ -181,7 +194,7 @@ long smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
 
         iop = fidp->ioctlp;
         count = smb_GetSMBParm(inp, 1);
-        userp = smb_GetUser(vcp, inp);
+        userp = smb_GetUserFromVCP(vcp, inp);
 
        /* Identify tree */
     code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
@@ -198,7 +211,7 @@ long smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
                return code;
         }
 
-       leftToCopy = (iop->outDatap - iop->outAllocp) - iop->outCopied;
+       leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied);
         if (count > leftToCopy) count = leftToCopy;
         
         /* now set the parms for a read of count bytes */
@@ -222,7 +235,6 @@ long smb_IoctlRead(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
         iop->outCopied += count;
         
         cm_ReleaseUser(userp);
-        smb_ReleaseFID(fidp);
 
         return 0;
 }
@@ -265,14 +277,58 @@ done:
                 smb_SetSMBDataLength(outp, 0);
         }
 
-        smb_ReleaseFID(fidp);
         return code;
 }
 
+/* called from smb_ReceiveV3WriteX when we receive a write call on the IOCTL
+ * file descriptor.
+ */
+long smb_IoctlV3Write(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
+{
+       smb_ioctl_t *iop;
+        long count;
+        long code;
+        char *op;
+        int inDataBlockCount;
+
+       code = 0;
+       count = smb_GetSMBParm(inp, 10);
+        iop = fidp->ioctlp;
+        
+       smb_IoctlPrepareWrite(fidp, iop);
+
+        op = inp->data + smb_GetSMBParm(inp, 11);
+        inDataBlockCount = count;
+       
+        if (count + iop->inCopied > SMB_IOCTL_MAXDATA) {
+               code = CM_ERROR_TOOBIG;
+                goto done;
+        }
+        
+       /* copy data */
+        memcpy(iop->inDatap + iop->inCopied, op, count);
+        
+        /* adjust counts */
+        iop->inCopied += count;
+
+done:
+       /* return # of bytes written */
+       if (code == 0) {
+               smb_SetSMBParm(outp, 2, count);
+                smb_SetSMBParm(outp, 3, 0); /* reserved */
+               smb_SetSMBParm(outp, 4, 0); /* reserved */
+               smb_SetSMBParm(outp, 5, 0); /* reserved */
+               smb_SetSMBDataLength(outp, 0);
+        }
+
+        return code;
+}
+
+
 /* called from V3 read to handle IOCTL descriptor reads */
 long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
 {
-       smb_ioctl_t *iop;
+    smb_ioctl_t *iop;
     long count;
     long code;
     long leftToCopy;
@@ -283,168 +339,165 @@ long smb_IoctlV3Read(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp, smb_pack
     iop = fidp->ioctlp;
     count = smb_GetSMBParm(inp, 5);
        
-       userp = smb_GetUser(vcp, inp);
-       osi_assert(userp != 0);
-
     uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+    userp = smb_GetUserFromUID(uidp);
+    osi_assert(userp != 0);
     iop->uidp = uidp;
-    if (uidp && uidp->unp)
+    if (uidp && uidp->unp) {
         osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
                   uidp->userID, userp,
                   osi_LogSaveString(afsd_logp, uidp->unp->name));
-    else {
+    } else {
         if (uidp)
-                   osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
-                      uidp->userID, userp);
+           osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
+                     uidp->userID, userp);
         else
-                   osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
-                     userp);
+           osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
+                    userp);
     }
 
-       code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
-    if(code) {
-        smb_ReleaseUID(uidp);
+    code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
+    if (code) {
+       if (uidp)
+           smb_ReleaseUID(uidp);
         cm_ReleaseUser(userp);
-        smb_ReleaseFID(fidp);
         return CM_ERROR_NOSUCHPATH;
     }
 
-       code = smb_IoctlPrepareRead(fidp, iop, userp);
+    code = smb_IoctlPrepareRead(fidp, iop, userp);
     if (uidp) {
         iop->uidp = 0;
         smb_ReleaseUID(uidp);
     }
     if (code) {
-               cm_ReleaseUser(userp);
-        smb_ReleaseFID(fidp);
-               return code;
+       cm_ReleaseUser(userp);
+       return code;
     }
 
-       leftToCopy = (iop->outDatap - iop->outAllocp) - iop->outCopied;
+    leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied);
     if (count > leftToCopy) count = leftToCopy;
         
-       /* 0 and 1 are reserved for request chaining, were setup by our caller,
-         * and will be further filled in after we return.
-         */
-        smb_SetSMBParm(outp, 2, 0);    /* remaining bytes, for pipes */
-        smb_SetSMBParm(outp, 3, 0);    /* resvd */
-        smb_SetSMBParm(outp, 4, 0);    /* resvd */
-       smb_SetSMBParm(outp, 5, count); /* # of bytes we're going to read */
-        /* fill in #6 when we have all the parameters' space reserved */
-        smb_SetSMBParm(outp, 7, 0);    /* resv'd */
-        smb_SetSMBParm(outp, 8, 0);    /* resv'd */
-        smb_SetSMBParm(outp, 9, 0);    /* resv'd */
-        smb_SetSMBParm(outp, 10, 0);   /* resv'd */
-       smb_SetSMBParm(outp, 11, 0);    /* reserved */
-
-       /* get op ptr after putting in the last parm, since otherwise we don't
-         * know where the data really is.
-         */
-        op = smb_GetSMBData(outp, NULL);
+    /* 0 and 1 are reserved for request chaining, were setup by our caller,
+     * and will be further filled in after we return.
+     */
+    smb_SetSMBParm(outp, 2, 0);        /* remaining bytes, for pipes */
+    smb_SetSMBParm(outp, 3, 0);        /* resvd */
+    smb_SetSMBParm(outp, 4, 0);        /* resvd */
+    smb_SetSMBParm(outp, 5, count);    /* # of bytes we're going to read */
+    /* fill in #6 when we have all the parameters' space reserved */
+    smb_SetSMBParm(outp, 7, 0);        /* resv'd */
+    smb_SetSMBParm(outp, 8, 0);        /* resv'd */
+    smb_SetSMBParm(outp, 9, 0);        /* resv'd */
+    smb_SetSMBParm(outp, 10, 0);       /* resv'd */
+    smb_SetSMBParm(outp, 11, 0);       /* reserved */
+
+    /* get op ptr after putting in the last parm, since otherwise we don't
+     * know where the data really is.
+     */
+    op = smb_GetSMBData(outp, NULL);
         
-        /* now fill in offset from start of SMB header to first data byte (to op) */
-        smb_SetSMBParm(outp, 6, ((int) (op - outp->data)));
+    /* now fill in offset from start of SMB header to first data byte (to op) */
+    smb_SetSMBParm(outp, 6, ((int) (op - outp->data)));
 
-       /* set the packet data length the count of the # of bytes */
-        smb_SetSMBDataLength(outp, count);
+    /* set the packet data length the count of the # of bytes */
+    smb_SetSMBDataLength(outp, count);
         
-       /* now copy the data into the response packet */
-        memcpy(op, iop->outCopied + iop->outAllocp, count);
+    /* now copy the data into the response packet */
+    memcpy(op, iop->outCopied + iop->outAllocp, count);
 
-        /* and adjust the counters */
-        iop->outCopied += count;
-        
-        /* and cleanup things */
-        cm_ReleaseUser(userp);
-        smb_ReleaseFID(fidp);
+    /* and adjust the counters */
+    iop->outCopied += count;
 
-        return 0;
-}
+    /* and cleanup things */
+    cm_ReleaseUser(userp);
+
+    return 0;
+}      
 
 /* called from Read Raw to handle IOCTL descriptor reads */
 long smb_IoctlReadRaw(smb_fid_t *fidp, smb_vc_t *vcp, smb_packet_t *inp,
-       smb_packet_t *outp
+                     smb_packet_t *outp
 #ifdef DJGPP
-, dos_ptr rawBuf
+                     , dos_ptr rawBuf
 #endif /* DJGPP */
-)
+                     )
 {
-       smb_ioctl_t *iop;
-       long leftToCopy;
-       NCB *ncbp;
-       long code;
-       cm_user_t *userp;
+    smb_ioctl_t *iop;
+    long leftToCopy;
+    NCB *ncbp;
+    long code;
+    cm_user_t *userp;
 #ifdef DJGPP
-        dos_ptr dos_ncb;
+    dos_ptr dos_ncb;
 
-        if (rawBuf == 0)
-        {
-                osi_Log0(afsd_logp, "Failed to get raw buf for smb_IoctlReadRaw");
-                return -1;
-        }
+    if (rawBuf == 0)
+    {
+       osi_Log0(afsd_logp, "Failed to get raw buf for smb_IoctlReadRaw");
+       return -1;
+    }
 #endif /* DJGPP */
 
-       iop = fidp->ioctlp;
-
-       userp = smb_GetUser(vcp, inp);
-
-       {
-               smb_user_t *uidp;
-
-               uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
-               if (uidp && uidp->unp)
-                   osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
-                            uidp->userID, userp,
-                            osi_LogSaveString(afsd_logp, uidp->unp->name));
-               else if (uidp)
-                   osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
-                            uidp->userID, userp);
-        else 
-                   osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
-                            userp);
-               if (uidp) smb_ReleaseUID(uidp);
+    iop = fidp->ioctlp;
+
+    userp = smb_GetUserFromVCP(vcp, inp);
+
+    /* Log the user */
+    {
+       smb_user_t *uidp;
+
+       uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+       if (uidp && uidp->unp) {
+           osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
+                    uidp->userID, userp,
+                    osi_LogSaveString(afsd_logp, uidp->unp->name));
+       } else if (uidp) {
+           osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
+                    uidp->userID, userp);
+       } else {
+           osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
+                    userp);
        }
+       if (uidp) 
+           smb_ReleaseUID(uidp);
+    }  
 
     code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &iop->tidPathp);
-    if(code) {
+    if (code) {
         cm_ReleaseUser(userp);
-        smb_ReleaseFID(fidp);
         return CM_ERROR_NOSUCHPATH;
     }
 
-       code = smb_IoctlPrepareRead(fidp, iop, userp);
-       if (code) {
-               cm_ReleaseUser(userp);
-               smb_ReleaseFID(fidp);
-               return code;
-       }
+    code = smb_IoctlPrepareRead(fidp, iop, userp);
+    if (code) {
+       cm_ReleaseUser(userp);
+       return code;
+    }
 
-       leftToCopy = (iop->outDatap - iop->outAllocp) - iop->outCopied;
+    leftToCopy = (long)((iop->outDatap - iop->outAllocp) - iop->outCopied);
 
-       ncbp = outp->ncbp;
-       memset((char *)ncbp, 0, sizeof(NCB));
+    ncbp = outp->ncbp;
+    memset((char *)ncbp, 0, sizeof(NCB));
 
-       ncbp->ncb_length = (unsigned short) leftToCopy;
-       ncbp->ncb_lsn = (unsigned char) vcp->lsn;
-       ncbp->ncb_command = NCBSEND;
+    ncbp->ncb_length = (unsigned short) leftToCopy;
+    ncbp->ncb_lsn = (unsigned char) vcp->lsn;
+    ncbp->ncb_command = NCBSEND;
     /*ncbp->ncb_lana_num = smb_LANadapter;*/
-       ncbp->ncb_lana_num = vcp->lana;
+    ncbp->ncb_lana_num = vcp->lana;
 
 #ifndef DJGPP
-       ncbp->ncb_buffer = iop->outCopied + iop->outAllocp;
-       code = Netbios(ncbp);
+    ncbp->ncb_buffer = iop->outCopied + iop->outAllocp;
+    code = Netbios(ncbp);
 #else /* DJGPP */
-        dosmemput(iop->outCopied + iop->outAllocp, ncbp->ncb_length, rawBuf);
-        ncbp->ncb_buffer = rawBuf;
-        dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
-       code = Netbios(ncbp, dos_ncb);
+    dosmemput(iop->outCopied + iop->outAllocp, ncbp->ncb_length, rawBuf);
+    ncbp->ncb_buffer = rawBuf;
+    dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
+    code = Netbios(ncbp, dos_ncb);
 #endif /* !DJGPP */
 
-       if (code != 0)
-               osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
+    if (code != 0)
+       osi_Log1(afsd_logp, "ReadRaw send failure code %d", code);
 
-       cm_ReleaseUser(userp);
-       smb_ReleaseFID(fidp);
+    cm_ReleaseUser(userp);
 
-       return 0;
+    return 0;
 }