Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
SMB2 bug cured?
Message
From
01/03/2011 19:31:12
 
 
To
01/03/2011 14:48:15
General information
Forum:
Visual FoxPro
Category:
Troubleshooting
Title:
Miscellaneous
Thread ID:
01502102
Message ID:
01502312
Views:
174
Likes (1)
Jos

This code is from Ron Chesley and not myself. It determines if the program is starting up on a W7 or Vista Work station.
If it is and the Cache times are not set to zero, it zeros out the 3 SMB2 Cache times.
*-  Smb2CacheFix.prg
*-  
*-  This process MUST be run on all workstations that participate
*-  in shared data access.
*-
*-  The VFP Registry class must already be available 
*-  via a SET CLASSLIB or SET PROCEDURE command.  
*-
#DEFINE HKEY_LOCAL_MACHINE  -2147483646    && BITSET(0,31)+2
#DEFINE SMB2_REGISTRY_PATH  "SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters"
#DEFINE REG_DWORD       4        && A 32-bit number.
#DEFINE ERROR_SUCCESS    0        && OK

PRIVATE pcDetail
LOCAL lcDefPath AS String;
  , lcOldErr AS String;
  , loRegistry AS "MyRegistry" 

*-  Detect Windows Vista OR Higher 
IF VAL(OS(3))=>6 
  
  *-  Detect SMB2 buffering
  loRegistry = NEWOBJECT("MyRegistry")  && See class definition below
  IF Smb2CachesData(loRegistry)
    
    *-  See if the user wants to change buffer settings
    IF MESSAGEBOX("Do you want to zero out the SMB2 cache settings?";
            ,32+4,"Problem with SMB2 Cache Settings")=6
      *-  Try to change the buffer settings
      lcOldErr = ON("Error")
      ON ERROR *
      loRegistry.DWORD_SetRegValue( HKEY_LOCAL_MACHINE;
                    , SMB2_REGISTRY_PATH;
                    , "FileInfoCacheLifetime";
                    , 0)
      loRegistry.DWORD_SetRegValue( HKEY_LOCAL_MACHINE;
                    , SMB2_REGISTRY_PATH;
                    , "FileNotFoundCacheLifetime";
                    , 0)
      loRegistry.DWORD_SetRegValue( HKEY_LOCAL_MACHINE;
                    , SMB2_REGISTRY_PATH;
                    , "DirectoryCacheLifetime";
                    , 0)
      ON ERROR &lcOldErr
      
      *-  Retest cache ettings and display the appropriate message
      IF Smb2CachesData(loRegistry)
        *-  Failure
        MESSAGEBOX("Failed to change the settings.";
        	+CHR(13)+CHR(13);
            +"Try to re-run this process with Administrator privileges.";
            ,16,"Status")
      ELSE
        *-  Success
        MESSAGEBOX("Succeeded in changing the SMB2 cache settings.";
        	+CHR(13)+CHR(13);
            +"You must reboot your computer for the changes to take affect.";
            ,64,"Status")
      ENDIF
      RETURN .F.  && Exit application
    ENDIF
  ENDIF
ENDIF


*******************************************
DEFINE CLASS MyRegistry AS Registry
  PROCEDURE DWORD_GetRegValue
    LPARAMETERS tnRegRoot, tcSubKey, tcOption
    LOCAL lnKeyHandle, lpdwType, lpcbData, lpbData, lnValue
    m.lnKeyHandle = 0
    m.lpdwType = REG_DWORD
    m.lpcbData = 4
    m.lpbData = REPLICATE(CHR(0),4)
    m.lnValue = 0

    * Load the API functions
    nErrCode = THIS.LoadRegFuncs()
    IF m.nErrCode # ERROR_SUCCESS
      RETURN .NULL.
    ENDIF

    IF RegOpenKey(tnRegRoot, tcSubKey, @lnKeyHandle) = ERROR_SUCCESS
      RegQueryValueEx(m.lnKeyHandle, tcOption, 0, @lpdwType, @lpbData, @lpcbData)
      RtlMoveMemory(@lnValue, lpbData, 4)
      RegCloseKey(m.lnKeyHandle)
      RETURN m.lnValue
    ELSE
      RETURN .NULL.
    ENDIF
  ENDPROC

  PROCEDURE DWORD_SetRegValue
    LPARAMETERS tnRegRoot, tcSubKey, tcOption, tnValue
    LOCAL lnKeyHandle,lpdwType,lpcbData,lpbData
    m.lnKeyHandle = 0
    m.lpdwType = REG_DWORD
    m.lpcbData = 4
    * Load the API functions
    nErrCode = THIS.LoadRegFuncs()
    IF m.nErrCode # ERROR_SUCCESS
      RETURN .NULL.
    ENDIF

    m.lpbData = BinToChar(tnValue, 4)
    
    IF RegOpenKey(tnRegRoot, tcSubKey, @lnKeyHandle) = ERROR_SUCCESS
      RegSetValueEx(m.lnKeyHandle,tcOption, 0, @lpdwType, @lpbData, @lpcbData)
      RegCloseKey(m.lnKeyHandle)
    ENDIF
  ENDPROC
ENDDEFINE


FUNCTION Smb2CachesData( toRegistry )
  LOCAL laSettings[1];
    , llRtnVal AS Boolean;
    , lnGoodSettings AS Number;
    , lnX AS Number
  
  *-  Get an array of registry settings
  DIMENSION laSettings[1]
  IF toRegistry.EnumOptions(@laSettings;
              , SMB2_REGISTRY_PATH;
              , HKEY_LOCAL_MACHINE;
              , .F.) = ERROR_SUCCESS
    *-  Test the cache settings.  
    *-  All three must be zero to pass
    lnGoodSettings = 0
    FOR lnX = 1 TO ALEN(laSettings, 1)
      IF VARTYPE(laSettings[lnX, 1])="C" ;  
          AND INLIST(UPPER(laSettings[lnX, 1]);
               , "DIRECTORYCACHELIFETIME";
               , "FILEINFOCACHELIFETIME";
               , "FILENOTFOUNDCACHELIFETIME");
          AND CharToBin(laSettings[lnX, 2])=0
        lnGoodSettings = lnGoodSettings + 1 
      ENDIF
    NEXT lnX
    llRtnVal = lnGoodSettings<3
  ENDIF
  RETURN llRtnVal
ENDFUNC


FUNCTION BinToChar( tnNum, tnByteSize )
  *- Converts a DWORD value in binary string form back into
  *- a numeric value
  LOCAL lnX, lcNum
  
  tnByteSize = IIF(VARTYPE(tnByteSize)="N", tnByteSize, 4)
  lcNum = ''
  FOR lnX=1 to tnByteSize
    lcNum = lcNum + CHR(INT(tnNum/(256^(lnX-1)))%256)
  NEXT
  RETURN lcNum
ENDFUNC


FUNCTION CharToBin( tcWord )
  *- Converts a DWORD value in binary string form back into
  *- a numeric value
  LOCAL lnX, lnWord
  
  lnWord = 0
  FOR lnX = 1 TO LEN(tcWord)
    lnWord = lnWord + (ASC(SUBSTR(tcWord, lnX, 1)) * (2 ^ (8 * (lnX - 1))))
  ENDFOR
  RETURN lnWord
ENDFUNC
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform