afsifs-20050615
[openafs.git] / src / WINNT / afsd / cm_ioctl.c
index b4d145f..29b83c9 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "afsd.h"
 #include "afsd_init.h"
+#include <WINNT\afsreg.h>
 
 #include "smb.h"
 #include "cm_server.h"
@@ -40,6 +41,8 @@
 
 #include "cm_rpc.h"
 #include <strsafe.h>
+#include <winioctl.h>
+#include <WINNT\afsrdr\kif.h>
 
 #ifdef _DEBUG
 #include <crtdbg.h>
@@ -71,11 +74,12 @@ long cm_FlushFile(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
     lock_ObtainMutex(&scp->mx);
     scp->cbServerp = NULL;
     scp->cbExpires = 0;
+    cm_dnlcPurgedp(scp);
+    cm_dnlcPurgevp(scp);
+    cm_FreeAllACLEnts(scp);
     lock_ReleaseMutex(&scp->mx);
 
     lock_ReleaseWrite(&scp->bufCreateLock);
-    cm_dnlcPurgedp(scp);
-
     return code;
 }
 
@@ -89,8 +93,8 @@ void cm_ResetACLCache(cm_user_t *userp)
     int hash;
 
     lock_ObtainWrite(&cm_scacheLock);
-    for (hash=0; hash < cm_hashTableSize; hash++) {
-        for (scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
+    for (hash=0; hash < cm_data.hashTableSize; hash++) {
+        for (scp=cm_data.hashTablep[hash]; scp; scp=scp->nextp) {
             cm_HoldSCacheNoLock(scp);
             lock_ReleaseWrite(&cm_scacheLock);
             lock_ObtainMutex(&scp->mx);
@@ -139,9 +143,11 @@ void TranslateExtendedChars(char *str)
 long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
        cm_scache_t **scpp)
 {
-    long code;
+    long code, length;
     cm_scache_t *substRootp;
-    char * relativePath = ioctlp->inDatap;
+    char * relativePath = ioctlp->inDatap, absRoot[100];
+       wchar_t absRoot_w[100];
+       HANDLE rootDir;
 
     /* This is usually the file name, but for StatMountPoint it is the path. */
     /* ioctlp->inDatap can be either of the form:
@@ -152,7 +158,47 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
      */
     TranslateExtendedChars(relativePath);
 
-    if (relativePath[0] == relativePath[1] &&
+#ifdef AFSIFS
+       /* we have passed the whole path, including the afs prefix (pioctl_nt.c modified) */
+       /*_asm int 3;
+       sprintf(absRoot, "%c:", relativePath[0]);
+       rootDir = CreateFile(absRoot, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+       if (!DeviceIoControl(rootDir, IOCTL_AFSRDR_GET_PATH, NULL, 0, absRoot_w, 100*sizeof(wchar_t), &length, NULL))
+               {
+               CloseHandle(rootDir);
+               return CM_ERROR_NOSUCHPATH;
+               }
+       CloseHandle(rootDir);
+
+       ifs_ConvertFileName(absRoot_w, length/sizeof(wchar_t), absRoot, 100);*/
+
+#if 0
+       switch (relativePath[0])                                        /* FIXFIX */
+               {
+               case 'y':
+               case 'Y':
+                       absRoot = "\\ericjw\\test";                     /* should use drivemap */
+               }
+#endif
+       code = cm_NameI(cm_data.rootSCachep, relativePath,
+                        CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
+                        userp, ""/*absRoot*//*ioctlp->tidPathp*/, reqp, scpp);
+
+       if (code)
+               return code;
+
+       /* # of bytes of path */
+    code = strlen(ioctlp->inDatap) + 1;
+    ioctlp->inDatap += code;
+
+    /* This is usually nothing, but for StatMountPoint it is the file name. */
+    TranslateExtendedChars(ioctlp->inDatap);
+
+       return 0;
+#endif
+
+       if (relativePath[0] == relativePath[1] &&
          relativePath[1] == '\\' && 
          !_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName))) 
     {
@@ -179,7 +225,7 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
         shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
         if ( shareFound ) {
             /* we found a sharename, therefore use the resulting path */
-            code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
+            code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
                              CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
                              userp, sharePath, reqp, &substRootp);
             free(sharePath);
@@ -208,7 +254,7 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
             shareName[i] = 0;       /* terminate string */
 
 
-            code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
+            code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
                              CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
                              userp, shareName, reqp, &substRootp);
             if (code) 
@@ -220,7 +266,7 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
                 return code;
         }
     } else {
-        code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
+        code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
                          CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
                          userp, ioctlp->tidPathp, reqp, &substRootp);
         if (code) 
@@ -347,7 +393,7 @@ long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
         shareFound = smb_FindShare(ioctlp->fidp->vcp, ioctlp->uidp, shareName, &sharePath);
         if ( shareFound ) {
             /* we found a sharename, therefore use the resulting path */
-            code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
+            code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
                              CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
                              userp, sharePath, reqp, &substRootp);
             free(sharePath);
@@ -373,7 +419,7 @@ long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
             shareName[i++] = '/';      /* add trailing slash */
             shareName[i] = 0;       /* terminate string */
 
-            code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
+            code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
                              CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
                              userp, shareName, reqp, &substRootp);
             if (code) return code;
@@ -383,7 +429,7 @@ long cm_ParseIoctlParent(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
             if (code) return code;
         }
     } else {
-        code = cm_NameI(cm_rootSCachep, ioctlp->prefix->data,
+        code = cm_NameI(cm_data.rootSCachep, ioctlp->prefix->data,
                         CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
                         userp, ioctlp->tidPathp, reqp, &substRootp);
         if (code) return code;
@@ -472,7 +518,7 @@ long cm_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp)
     {
         cellp = cm_FindCellByID(scp->fid.cell);
         if (cellp) {
-            StringCbCopyA(ioctlp->outDatap, 999999, cellp->namep);
+            StringCbCopyA(ioctlp->outDatap, 999999, cellp->name);
             ioctlp->outDatap += strlen(ioctlp->outDatap) + 1;
             code = 0;
         }
@@ -545,8 +591,8 @@ long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cm_ReleaseSCache(scp);
 
     lock_ObtainWrite(&cm_scacheLock);
-    for (i=0; i<cm_hashTableSize; i++) {
-        for (scp = cm_hashTablep[i]; scp; scp = scp->nextp) {
+    for (i=0; i<cm_data.hashTableSize; i++) {
+        for (scp = cm_data.hashTablep[i]; scp; scp = scp->nextp) {
             if (scp->fid.volume == volume) {
                 cm_HoldSCacheNoLock(scp);
                 lock_ReleaseWrite(&cm_scacheLock);
@@ -974,10 +1020,10 @@ long cm_IoctlSetCacheSize(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
     memcpy(&temp, ioctlp->inDatap, sizeof(temp));
     if (temp == 0) 
-        temp = buf_nOrigBuffers;
+        temp = cm_data.buf_nOrigBuffers;
     else {
         /* temp is in 1K units, convert to # of buffers */
-        temp = temp / (buf_bufferSize / 1024);
+        temp = temp / (cm_data.buf_blockSize / 1024);
     }       
 
     /* now adjust the cache size */
@@ -1031,12 +1077,12 @@ long cm_IoctlGetCacheParms(struct smb_ioctl *ioctlp, struct cm_user *userp)
     memset(&parms, 0, sizeof(parms));
 
     /* first we get, in 1K units, the cache size */
-    parms.parms[0] = buf_nbuffers * (buf_bufferSize / 1024);
+    parms.parms[0] = cm_data.buf_nbuffers * (cm_data.buf_blockSize / 1024);
 
     /* and then the actual # of buffers in use (not in the free list, I guess,
      * will be what we do).
      */
-    parms.parms[1] = (buf_nbuffers - buf_CountFreeList()) * (buf_bufferSize / 1024);
+    parms.parms[1] = (cm_data.buf_nbuffers - buf_CountFreeList()) * (cm_data.buf_blockSize / 1024);
 
     memcpy(ioctlp->outDatap, &parms, sizeof(parms));
     ioctlp->outDatap += sizeof(parms);
@@ -1069,7 +1115,7 @@ long cm_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
     }
 
     lock_ObtainRead(&cm_cellLock);
-    for (tcellp = cm_allCellsp; tcellp; tcellp = tcellp->nextp) {
+    for (tcellp = cm_data.allCellsp; tcellp; tcellp = tcellp->nextp) {
         if (whichCell == 0) break;
         whichCell--;
     }
@@ -1097,8 +1143,8 @@ long cm_IoctlGetCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
         }
         lock_ReleaseRead(&cm_serverLock);
         cp = basep + max * sizeof(afs_int32);
-        StringCbCopyA(cp, 999999, tcellp->namep);
-        cp += strlen(tcellp->namep)+1;
+        StringCbCopyA(cp, 999999, tcellp->name);
+        cp += strlen(tcellp->name)+1;
         ioctlp->outDatap = cp;
     }
 
@@ -1112,7 +1158,7 @@ extern long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *namep);
 
 long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
 {
-    /* NT cache manager will read cell information from afsdcell.ini each time
+    /* NT cache manager will read cell information from CellServDB each time
      * cell is accessed. So, this call is necessary only if list of server for a cell 
      * changes (or IP addresses of cell servers changes).
      * All that needs to be done is to refresh server information for all cells that 
@@ -1126,18 +1172,18 @@ long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cm_SkipIoctlPath(ioctlp);
     lock_ObtainWrite(&cm_cellLock);
   
-    for (cp = cm_allCellsp; cp; cp=cp->nextp) 
+    for (cp = cm_data.allCellsp; cp; cp=cp->nextp) 
     {
         long code;
         /* delete all previous server lists - cm_FreeServerList will ask for write on cm_ServerLock*/
         cm_FreeServerList(&cp->vlServersp);
         cp->vlServersp = NULL;
-        code = cm_SearchCellFile(cp->namep, cp->namep, cm_AddCellProc, cp);
+        code = cm_SearchCellFile(cp->name, cp->name, cm_AddCellProc, cp);
 #ifdef AFS_AFSDB_ENV
         if (code) {
             if (cm_dnsEnabled) {
                 int ttl;
-                code = cm_SearchCellByDNS(cp->namep, cp->namep, &ttl, cm_AddCellProc, cp);
+                code = cm_SearchCellByDNS(cp->name, cp->name, &ttl, cm_AddCellProc, cp);
                 if ( code == 0 ) { /* got cell from DNS */
                     cp->flags |= CM_CELLFLAG_DNS;
                     cp->flags &= ~CM_CELLFLAG_VLSERVER_INVALID;
@@ -1164,17 +1210,21 @@ long cm_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
 long cm_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp)
 {
-    /* if we don't know our default cell, return failure */
-    if (cm_rootCellp == NULL) {
-        return CM_ERROR_NOSUCHCELL;
+       long code = 0;
+
+       if (cm_freelanceEnabled) {
+           StringCbCopyA(ioctlp->outDatap, 999999, "Freelance.Local.Root");
+               ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
+       } else if (cm_data.rootCellp) {
+           /* return the default cellname to the caller */
+           StringCbCopyA(ioctlp->outDatap, 999999, cm_data.rootCellp->name);
+           ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
+       } else {
+           /* if we don't know our default cell, return failure */
+               code = CM_ERROR_NOSUCHCELL;
     }
 
-    /* return the default cellname to the caller */
-    StringCbCopyA(ioctlp->outDatap, 999999, cm_rootCellp->namep);
-    ioctlp->outDatap += strlen(ioctlp->outDatap) +1;
-
-    /* done: success */
-    return 0;
+    return code;
 }
 
 long cm_IoctlSysName(struct smb_ioctl *ioctlp, struct cm_user *userp)
@@ -1348,12 +1398,13 @@ long cm_IoctlSetSPrefs(struct smb_ioctl *ioctlp, struct cm_user *userp)
         {
             tsp->ipRank = rank; /* no need to protect by mutex*/
 
-            if ( type == CM_SERVER_FILE) /* fileserver */
-            {
+            if (type == CM_SERVER_FILE)
+            {   /* fileserver */
                 /* find volumes which might have RO copy 
                 /* on server and change the ordering of 
-                ** their RO list */
-                    cm_ChangeRankVolume(tsp);
+                 * their RO list 
+                 */
+                cm_ChangeRankVolume(tsp);
             }
             else       
             {
@@ -1477,7 +1528,7 @@ long cm_IoctlCreateMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
     }
 
 #ifdef AFS_FREELANCE_CLIENT
-    if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
+    if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
         /* we are adding the mount point to the root dir., so call
          * the freelance code to do the add. */
         osi_Log0(afsd_logp,"IoctlCreateMountPoint within Freelance root dir");
@@ -1526,7 +1577,7 @@ long cm_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cp = ioctlp->inDatap;              /* contents of link */
 
 #ifdef AFS_FREELANCE_CLIENT
-    if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
+    if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
         /* we are adding the symlink to the root dir., so call
          * the freelance code to do the add. */
         if (cp[0] == cp[1] && cp[1] == '\\' && 
@@ -1561,9 +1612,6 @@ long cm_IoctlSymlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
     return code;
 }
 
-extern long cm_AssembleLink(cm_scache_t *linkScp, char *pathSuffixp,
-                            cm_scache_t **newRootScpp, cm_space_t **newSpaceBufferp,
-                            cm_user_t *userp, cm_req_t *reqp);
 
 long cm_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
 {
@@ -1587,7 +1635,9 @@ long cm_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
     if (code) return code;
 
     /* Check that it's a real symlink */
-    if (scp->fileType != CM_SCACHETYPE_SYMLINK){
+    if (scp->fileType != CM_SCACHETYPE_SYMLINK &&
+        scp->fileType != CM_SCACHETYPE_DFSLINK &&
+        scp->fileType != CM_SCACHETYPE_INVALID) {
         cm_ReleaseSCache(scp);
         return CM_ERROR_INVAL;
     }
@@ -1607,7 +1657,20 @@ long cm_IoctlListlink(struct smb_ioctl *ioctlp, struct cm_user *userp)
         cm_FreeSpace(spacep);
         if (newRootScp != NULL)
             cm_ReleaseSCache(newRootScp);
-    }       
+        code = 0;
+    } else if (code == CM_ERROR_PATH_NOT_COVERED && 
+                scp->fileType == CM_SCACHETYPE_DFSLINK ||
+               code == CM_ERROR_NOSUCHPATH &&
+                scp->fileType == CM_SCACHETYPE_INVALID) {
+        cp = ioctlp->outDatap;
+        StringCbCopyA(cp, 999999, spacep->data);
+        cp += strlen(cp) + 1;
+        ioctlp->outDatap = cp;
+        cm_FreeSpace(spacep);
+        if (newRootScp != NULL)
+            cm_ReleaseSCache(newRootScp);
+        code = 0;
+    }
 
     return code;
 }
@@ -1633,7 +1696,9 @@ long cm_IoctlIslink(struct smb_ioctl *ioctlp, struct cm_user *userp)
     if (code) return code;
 
     /* Check that it's a real symlink */
-    if (scp->fileType != CM_SCACHETYPE_SYMLINK)
+    if (scp->fileType != CM_SCACHETYPE_SYMLINK &&
+        scp->fileType != CM_SCACHETYPE_DFSLINK &&
+        scp->fileType != CM_SCACHETYPE_INVALID)
         code = CM_ERROR_INVAL;
     cm_ReleaseSCache(scp);
     return code;
@@ -1655,7 +1720,7 @@ long cm_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cp = ioctlp->inDatap;
 
 #ifdef AFS_FREELANCE_CLIENT
-    if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
+    if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
         /* we are adding the mount point to the root dir., so call
          * the freelance code to do the add. */
         osi_Log0(afsd_logp,"IoctlDeletelink from Freelance root dir");
@@ -1681,7 +1746,9 @@ long cm_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
     }
        
     /* now check that this is a real symlink */
-    if (scp->fileType != CM_SCACHETYPE_SYMLINK) {
+    if (scp->fileType != CM_SCACHETYPE_SYMLINK &&
+        scp->fileType != CM_SCACHETYPE_DFSLINK &&
+        scp->fileType != CM_SCACHETYPE_INVALID) {
         lock_ReleaseMutex(&scp->mx);
         cm_ReleaseSCache(scp);
         code = CM_ERROR_INVAL;
@@ -1764,7 +1831,8 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
         uname = tp;
         tp += strlen(tp) + 1;
 
-        if (flags & PIOCTL_LOGON) {
+#ifndef AFSIFS                 /* no SMB username */
+               if (flags & PIOCTL_LOGON) {
             /* SMB user name with which to associate tokens */
             smbname = tp;
             osi_Log2(smb_logp,"cm_IoctlSetToken for user [%s] smbname [%s]",
@@ -1775,6 +1843,7 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
             osi_Log1(smb_logp,"cm_IoctlSetToken for user [%s]",
                      osi_LogSaveString(smb_logp,uname));
         }
+#endif
 
 #ifndef DJGPP   /* for win95, session key is back in pioctl */
                /* uuid */
@@ -1783,7 +1852,7 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
             return CM_ERROR_INVAL;
 #endif /* !DJGPP */
     } else {
-        cellp = cm_rootCellp;
+        cellp = cm_data.rootCellp;
         osi_Log0(smb_logp,"cm_IoctlSetToken - no name specified");
     }
 
@@ -1902,7 +1971,7 @@ long cm_IoctlGetTokenIter(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cp += sizeof(temp);
 
     /* cell name */
-    StringCbCopyA(cp, 999999, ucellp->cellp->namep);
+    StringCbCopyA(cp, 999999, ucellp->cellp->name);
     cp += strlen(cp) + 1;
 
     /* user name */
@@ -1936,7 +2005,8 @@ long cm_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
     /* cell name is right here */
     cellp = cm_GetCell(tp, 0);
-    if (!cellp) return CM_ERROR_NOSUCHCELL;
+    if (!cellp) 
+        return CM_ERROR_NOSUCHCELL;
     tp += strlen(tp) + 1;
 
 #ifndef DJGPP
@@ -1990,7 +2060,7 @@ long cm_IoctlGetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cp += sizeof(temp);
 
     /* cell name */
-    StringCbCopyA(cp, 999999, ucellp->cellp->namep);
+    StringCbCopyA(cp, 999999, ucellp->cellp->name);
     cp += strlen(cp) + 1;
 
     /* user name */
@@ -2095,7 +2165,7 @@ long cm_IoctlMakeSubmount(smb_ioctl_t *ioctlp, cm_user_t *userp)
      */
 
     RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
-                    "SOFTWARE\\OpenAFS\\Client\\Submounts",
+                    AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts",
                     0, 
                     "AFS", 
                     REG_OPTION_NON_VOLATILE,
@@ -2283,9 +2353,9 @@ long cm_IoctlGetSMBName(smb_ioctl_t *ioctlp, cm_user_t *userp)
  * functions to dump contents of various structures. 
  * In debug build (linked with crt debug library) will dump allocated but not freed memory
  */
-extern int cm_DumpSCache(FILE *outputFile, char *cookie);
-extern int cm_DumpBufHashTable(FILE *outputFile, char *cookie);
-extern int smb_DumpVCP(FILE *outputFile, char *cookie);
+extern int cm_DumpSCache(FILE *outputFile, char *cookie, int lock);
+extern int cm_DumpBufHashTable(FILE *outputFile, char *cookie, int lock);
+extern int smb_DumpVCP(FILE *outputFile, char *cookie, int lock);
 
 long cm_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
 {
@@ -2293,6 +2363,7 @@ long cm_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
     HANDLE hLogFile;
     char logfileName[MAX_PATH+1];
     char *cookie;
+    DWORD dwSize;
   
 #ifdef _DEBUG  
     static _CrtMemState memstate;
@@ -2301,12 +2372,8 @@ long cm_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cm_SkipIoctlPath(ioctlp);
     memcpy(&inValue, ioctlp->inDatap, sizeof(long));
   
-    if (getenv("TEMP"))
-    {
-        strncpy(logfileName, getenv("TEMP"), MAX_PATH);
-        logfileName[MAX_PATH] = '\0';
-    }
-    else
+    dwSize = GetEnvironmentVariable("TEMP", logfileName, sizeof(logfileName));
+    if ( dwSize == 0 || dwSize > sizeof(logfileName) )
     {
         GetWindowsDirectory(logfileName, sizeof(logfileName));
     }
@@ -2343,9 +2410,9 @@ long cm_IoctlMemoryDump(struct smb_ioctl *ioctlp, struct cm_user *userp)
 #endif
   
     /* dump all interesting data */
-    cm_DumpSCache(hLogFile, cookie);
-    cm_DumpBufHashTable(hLogFile, cookie);
-    smb_DumpVCP(hLogFile, cookie);
+    cm_DumpSCache(hLogFile, cookie, 1);
+    cm_DumpBufHashTable(hLogFile, cookie, 1);
+    smb_DumpVCP(hLogFile, cookie, 1);
 
     CloseHandle(hLogFile);