Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
How to detect open/locked files in Microsoft Network
Message
De
27/09/2013 10:41:33
 
 
À
27/09/2013 10:30:35
Information générale
Forum:
Visual FoxPro
Catégorie:
Produits tierce partie
Versions des environnements
Visual FoxPro:
VFP 9 SP2
OS:
Windows Server 2012
Network:
Windows 2008 Server
Database:
Visual FoxPro
Application:
Web
Divers
Thread ID:
01584325
Message ID:
01584327
Vues:
88
J'aime (1)
>Hello,
>our company is in a process of switching from Nowell network to Microsoft.
>On Nowell I used WhohasIt software for detecting open files, file locks and clearing locks on network drives.
>Now I tried WhoHasItNT, but found this one works much worse. It does not show me real file locks and does not allow to sort by path/file name.
>Can anybody tell me what will be the good replacement of WhoHasIt in Microsoft network.
>Thank you very much.

Since this is a VFP forum, I will show you a program I used for a similar purpose many years ago.
*-- For Windows NT Platform (NT 4, NT 2000)
*
* Modified version of Paul Vlad Tatavu file:
*   Who opened what files on the network?
*
* This one doesn't use the Pointers.OCX or Pointers.VCX
* It's only Visual Foxpro Code.
*
*--
* The following program displays the open files, the users that 
* opened these files and other related information.
*
* This code detects only the files opened using a net shared 
* path. It does not return the files opened by a user on the 
* local computer using a local path (i.e. the computer where 
* the user is logged on). This is normal, because, otherwise, 
* the number of returned files would be huge.
*
* The user running this program must be a member of the 
* Administrators or Account Operators local group.
*
* In order to keep the code simple, the error handling only 
* displays the error code. You should integrate it in your 
* error handling mechanism.
*
*-- This function returns information about open files.
*   It returns the open files only if they were
*   opened using a share on that computer.
*
*-- It uses:
*      - The NetFileEnum Win32 API function
*        to retrieve the wanted information from the OS.
*
*-- Parameters:
*      1. The server name. It can also be a domain name.
*         Use an empty string for the current computer.
*         Ex: MyServer
*      2. The base path. Only the files in this directory
*         (and all subdirectories) will be returned.
*         This path must be specified as the local path
*         on the computer where the files were opened, and
*         not as the UNC path.
*      3. The user name.
*         Use an empty string for all users. 
*--

#DEFINE VER_PLATFORM_WIN32S         0
#DEFINE VER_PLATFORM_WIN32_WINDOWS  1
#DEFINE VER_PLATFORM_WIN32_NT       2

PROCEDURE FileUse
  LPARAMETERS tcServerName, tcBasePath, tcUserName

  LOCAL lnmajor, lnminor, lnplatform, lnbuild
  GetOSVersion(@lnmajor, @lnminor, @lnplatform, @lnbuild)
  IF lnplatform # VER_PLATFORM_WIN32_NT
     ? 'Requires Windows NT...'
     RETURN
  ENDIF
  
  IF Type('tcServerName')#'C' .or. Type('tcBasePath')#'C' .or. Type('tcUserName')#'C'
    ? 'Invalid Parameters...'
    RETURN
  ENDIF

  LOCAL lcServerName, lcBasePath, lcUserName, lnBufferPointer
  LOCAL lnPreferedMaxLength, lnEntriesRead, lnTotalEntries
  LOCAL lnResumeHandle, lnError
  LOCAL loPointersObject
  LOCAL lnI, lcDll, lnPermissions, lnID
  LOCAL llContinue, lnpFileInfo, lcFileName
  LOCAL lnLocks, lcUserName

  DECLARE INTEGER NetFileEnum IN NETAPI32              ;
    STRING  @ServerName, STRING  @BasePath,            ;
    STRING  @UserName, INTEGER nLevel,                 ;
    INTEGER  @BufferPointer, INTEGER PreferedMaxLength, ;
    INTEGER @EntriesRead, INTEGER @TotalEntries,       ;
    INTEGER @ResumeHandle

  DECLARE INTEGER NetApiBufferFree IN NETAPI32 ;
    INTEGER Pointer

  *-- This is the structure used by NetFileEnum
  *   to retrieve the information.
  *typedef struct _FILE_INFO_3 {
  * DWORD fi3_id;
  * DWORD fi3_permissions;
  * DWORD fi3_num_locks;
  * LPWSTR fi3_pathname;
  * LPWSTR fi3_username;} FILE_INFO_3

  *-- The server name, the base path and the user name
  *   must be in Unicode format.
  lcServerName = StrConv(StrConv(tcServerName + Chr(0), 1), 5)
  lcBasePath   = StrConv(StrConv(tcBasePath + Chr(0), 1), 5)
  lcUserName   = StrConv(StrConv(tcUserName + Chr(0), 1), 5)

  *-- Allow for a very large buffer.
  *   If this length is not enough, the info
  *   will be retrieved in more than one step.
  lnPreferedMaxLength = 100000000

  lnResumeHandle  = 0
  lnEntriesRead   = 0
  lnTotalEntries  = 0
  lnBufferPointer = 0

  llContinue = .t.
  DO WHILE llContinue
    lnError = NetFileEnum( lcServerName, lcBasePath, lcUserName, 3, ;
              @lnBufferPointer, lnPreferedMaxLength, @lnEntriesRead, ;
              @lnTotalEntries, @lnResumeHandle)
    IF lnEntriesRead = 0
      *-- There are no (more) open files.
      llContinue = .f.
    ENDIF
    IF lnError = 0
      FOR lnI = 1 TO lnEntriesRead
        ?
        lnpFileInfo = lnBufferPointer + (lnI - 1) * 20
      
        *-- Extract the file name
        lcFileName = GetMemoryLPString(lnpFileInfo + 12)
        ? "File name:", lcFileName
      
        *-- Extract the number of locks on this file
        lnLocks = GetMemoryDWORD(lnpFileInfo + 8)
        ? "Locks:", lnLocks
      
        *-- Extract the user name that opened the file
        lcUserName = GetMemoryLPString(lnpFileInfo + 16)
        ? "User:", lcUserName
      
        *-- Extract the permissions on this file
        lnPermissions = GetMemoryDWORD( lnpFileInfo + 4)

        ? "Permissions:"
        IF BitTest(lnPermissions, 0)
          ?? "Read "
        ENDIF
        IF BitTest(lnPermissions, 1)
          ?? "Write "
        ENDIF
        IF BitTest(lnPermissions, 2)
          ?? "Create "
        ENDIF
        IF BitTest(lnPermissions, 3)
          ?? "Execute "
        ENDIF
        IF BitTest(lnPermissions, 4)
          ?? "Delete "
        ENDIF
        IF BitTest(lnPermissions, 5)
          ?? "ChangeAttributes "
        ENDIF
        IF BitTest(lnPermissions, 6)
          ?? "ChangeACL "
        ENDIF
      
        *-- Extract the ID for this file.
        *   This ID is generated when the file is opened and
        *   can be used as parameter for the NetFileGetInfo
        *   Win32 API function.
        lnID = GetMemoryDWORD(lnpFileInfo)
        ? "ID for NetFileGetInfo():", lnID
      ENDFOR
    
      *-- Free the memory allocated by NetFileEnum
      IF lnBufferPointer <> 0
        NetApiBufferFree(lnBufferPointer)
      ENDIF
    ELSE
      ? "Error", lnError
      llContinue = .f.
    ENDIF
  ENDDO
ENDPROC
*-- 
*  Get the OS Version and platform
*--
PROCEDURE GetOSVersion
   LParameter m.major, m.minor, m.platform, m.build
   Local m.osversion

   Declare GetVersionEx IN win32api String @OSVERSIONINFO

   * The OSVERSIONINFO structure is 148 bytes long.
   m.osversion = long2str(148) + Replicate(Chr(0), 144)
   =GetVersionEx(@m.osversion)
   m.major = str2long(Substr(m.osversion, 5, 4))
   m.minor = str2long(Substr(m.osversion, 9, 4))
   m.build = str2long(Substr(m.osversion, 13, 4))
   m.platform = str2long(Substr(m.osversion, 17, 4))
   m.build = BitAnd(m.build, 0xFFFF)
ENDPROC
*--
*  Return a Unicode from a pointer to LPWString
*--
FUNCTION GetMemoryLPString
  LParameter m.nPointer, m.nPlatform
  Local m.cResult, m.nLPStr, m.nslen
  
  m.nLPStr = GetMemoryDWORD(m.nPointer)

  DECLARE RtlMoveMemory IN Kernel32 String@ dest, Integer src, Integer nsize
  DECLARE Integer lstrlenW IN Kernel32 Integer src

  m.nslen = lstrlenW(m.nLPStr) * 2
  m.cResult = Replicate(chr(0), m.nslen)
  RtlMoveMemory(@m.cResult, m.nLPStr, m.nslen)
  m.cResult = StrConv(StrConv(m.cResult, 6), 2)

  RETURN m.cResult
ENDFUNC
*--
*  Return Number from a pointer to DWORD
*--
FUNCTION GetMemoryDWORD
  LParameter m.nPointer
  Local m.cstrDWORD

  DECLARE RtlMoveMemory IN  Kernel32 String@ dest, Integer src, Integer nsize
  m.cstrDWORD = Replicate(chr(0), 4)
  RtlMoveMemory(@m.cstrDWORD, m.nPointer, 4)
  RETURN str2long(m.cstrDWORD)
ENDFUNC
*-- 
*   Convert a Number intto a binary Long Integer
*--
FUNCTION long2str
  LParameter m.nLong

  m.nLong = Int(m.nLong)
  RETURN (chr(bitand(m.nLong,255))                 + ;
          chr(bitand(bitrshift(m.nLong,  8), 255)) + ;
          chr(bitand(bitrshift(m.nLong, 16), 255)) + ;
          chr(bitand(bitrshift(m.nLong, 24), 255)))
ENDFUNC
*-- 
*   Convert a binary Long Integer into a Number
*--
FUNCTION str2long
  LParameter m.cpLong
  Return (Bitlshift(Asc(Substr(m.cpLong, 4, 1)), 24) + ;
          Bitlshift(Asc(Substr(m.cpLong, 3, 1)), 16) + ;
          Bitlshift(Asc(Substr(m.cpLong, 2, 1)),  8) + ;
          Asc(Substr(m.cpLong, 1, 1)))
ENDFUNC
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform