excelvbafile-locking

GetSecurityDescriptor parameters


I was looking for a function to find the username locking a file.

I found this one which works fine:

Function GetUsername(fileDir As String, fileName As String) As String

'On Error Resume Next
Dim secUtil As Object
Dim secDesc As Object

Set secUtil = CreateObject("ADsSecurityUtility")
Set secDesc = secUtil.GetSecurityDescriptor(fileDir & fileName, 1, 1)

GetUsername = secDesc.Owner

End Function

I wanted to change

Set secDesc = secUtil.GetSecurityDescriptor(fileDir & fileName, 1, 1)

For

Set secDesc = secUtil.GetSecurityDescriptor(fullFileName, 1, 1)

I made the required change at the function declaration, even tried without any function but couldn't make the method work with a unique variable containing the full path, forcing me to split it for a reason I don't understand.

Here are the full function (well translated I hope)

Function GetUsername(fileDir As String, fileName As String) As 
String 'case 1
'Function GetUsername(fullFileName As String) As String 'case 2

Dim secUtil As Object
Dim secDesc As Object

Set secUtil = CreateObject("ADsSecurityUtility")
Set secDesc = secUtil.GetSecurityDescriptor(fileDir & fileName, 1, 1) 'case 1
'Set secDesc = secUtil.GetSecurityDescriptor(fullFileName, 1, 1) 'case 2

GetUsername = secDesc.Owner

End Function


Function IsOpen(file As String) As Boolean

Dim filenum As Integer, errnum As Integer

On Error Resume Next
filenum = FreeFile()

Open file For Input Lock Read As #filenum
Close filenum
errnum = Err
On Error GoTo 0

Select Case errnum
    Case 0
        IsOpen = False
    Case 70
        IsOpen = True
    Case Else
        Error errnum
End Select
End Function


Function CheckFile(file As String) As Boolean

'existence test
Set fs = CreateObject("Scripting.FileSystemObject")

If fs.fileexists(file) = True Then 'the file exists
    If IsOpen(file) = True Then 'the file is open
        MsgBox "file opened" & Chr(10) & "By : " & GetUsername("R\", "TEST.xlsx") 'case 1 : works
        'MsgBox "file opened" & Chr(10) & "By : " & GetUsername(file) 'case 2 : don't works
    Else
        MsgBox "closed file"
    End If
Else
    MsgBox "ERROR: The file does not exists"
End If

End Function


Private Sub TestOpen()

Dim ftest As String

ftest = "R:\TEST.xlsx"

CheckFile (ftest)

End Sub

Solution

  • The documentation for GetSecurityDescriptor seems rather emphatic that the first parameter must be a variant.

    A VARIANT string that contains the path of the object to retrieve the security descriptor for.

    I tried your revised code and sure enough it did not work. However, after making one small change to force the parameter to variant the code worked fine.

    Set secDesc = secUtil.GetSecurityDescriptor(CVar(fullFileName), 1, 1)
    

    So what is the difference between case 1 and case 2 from your question? I don't know. But it seems the result of concatenating 2 strings is a variant which is why case 1 worked.