Solved

Get API results

Posted on 2001-06-04
9
484 Views
Last Modified: 2008-02-26
API call s return a long datatype. The probleem I'm having is I need the other information it is actuly calling.

Example:

Private Declare Function GetFullPathName Lib "kernel32" Alias "GetFullPathNameA" (ByVal lpFileName As String, ByVal nBufferLength As Long, ByVal lpBuffer As String, ByVal lpFilePart As String) As Long


I need the FullPathName and all I receive is a Long Datatype. A'm I missing something really simple or is the Long datatype returned a pointer to the string. If it is a pointer, how do I get the string it's pointing to?
0
Comment
Question by:rtcomp
9 Comments
 
LVL 2

Expert Comment

by:kiprimshot
ID: 6154226
you can't access it by setting a variable = lpFileName ??
0
 
LVL 7

Expert Comment

by:Z_Beeblebrox
ID: 6154252
The file path will be returned in lpBuffer. The resulting long of the function call is the length of the string. See http://www.allapi.net/api/GetFullPathName.php

Zaphod.
0
 
LVL 7

Expert Comment

by:Z_Beeblebrox
ID: 6154256
The example makes it very clear:

http://www.allapi.net/api/api149.php

Zaphod.
0
 
LVL 2

Expert Comment

by:TravisHall
ID: 6154330
The return value from most API functions just tells you whether the function call succeeded (sometimes why it didn't succeed) or sometimes how big a buffer you need to make the thing work. The particular example you use is one of the second type. The return value is the size of the buffer you must give it to put the full path in.

To actually get that path, you need to pass it a string variable for the buffer parameter, and when the function returns, that variable will hold the string you are looking for.

However, just to complicate things a little, you need to actually assign a buffer of the correct length (or more), generally using the String$ function. For example, to use the API function you defined:

Dim sFilePath As String
Dim sFilePart As String
Dim lBufLen As Long

'We don't know how big a buffer we need, so let's ask
lBufLen = GetFullPathName("blah.txt", 0, sFilePath, sFilePart)

'By allocating a string of null characters, we reserve
'the necessary buffer space
sFilePath = String$(lBufLen, 0)

'And finally, get our path
lBufLen = GetFullPathName("blah.txt", lBufLen, sFilePath, sFilePart)

'Let's have a look at what path we end up with
Debug.Print sFilePath


There are some additional things to be aware of. The string you get back will be null terminated - so basically, you get an extra null character at the end of it. You can manipulate the string to get rid of the null character after the call to GetFullPathName, or you can just allocated one character less, thus:
sFilePath = String$(lBufLen - 1, 0)

It works in this case, but I wouldn't count on it for all other API functions. GetFullPathName fills the buffer with what it can, which is everything but the null character. The null character is discarded - exactly what we want. However, do check lBufLen before doing this, because if the first call to GetFullPathName fails, you will get back 0, and then try to allocated a string of length -1.

Also, part of this API function doesn't work right in VB - at least not as defined. sFilePart in my code above won't actually give you the file part. If you changed the definition so that this is a long instead of a string, I guess you would get back a valid pointer value, but that's hard to work with in VB. (In C, it could be useful.) Anyway, just don't count on that last parameter doing anything useful for you.
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 2

Expert Comment

by:Microsoft
ID: 6161244
TRY THIS :-

Option Explicit

Private Const MAX_PATH = 260
Private Const FILE_ATTRIBUTE_DIRECTORY = &H10
Private Const FILE_ATTRIBUTE_SYSTEM = &H4
Private Const FILE_ATTRIBUTE_HIDDEN = &H2
Private Const FILE_ATTRIBUTE_READONLY = &H1
Private Const ERROR_NO_MORE_FILES = 18&

Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
    dwFileAttributes As Long
    ftCreationTime As FILETIME
    ftLastAccessTime As FILETIME
    ftLastWriteTime As FILETIME
    nFileSizeHigh As Long
    nFileSizeLow As Long
    dwReserved0 As Long
    dwReserved1 As Long
    cFileName As String * MAX_PATH
    cAlternate As String * 14
End Type

Private Declare Function FindFirstFile Lib "kernel32" _
   Alias "FindFirstFileA" (ByVal lpFileName As String, _
   lpFindFileData As WIN32_FIND_DATA) As Long
   
Private Declare Function FindNextFile Lib "kernel32" Alias _
   "FindNextFileA" (ByVal hFindFile As Long, _
   lpFindFileData As WIN32_FIND_DATA) As Long

Private Declare Function FindClose Lib "kernel32" _
   (ByVal hFindFile As Long) As Long
Public Function AllFiles(ByVal DirPath As String) As String()
'***************************************************
'PURPOSE: RETURN AN ARRAY CONTAINING NAME OF ALL FILES IN
'DIRECTORY SPECIFIED BY DIR PATH


'PARAMETER:

  'DIRPATH: A VALID DRIVE OR SUBDIRECTORY ON YOUR SYSTEM,
  'ENDING WITH FORWARD SLASH (\) CHARACTER, OR
  'A DRIVE OR SUBDIRECTORY FOLLOWED BY A WILD CARD
  'STRING (e.g., C:\WINDOWS\*.txt)

'RETURNS: A STRING ARRAY WITH THE NAMES OF ALL FILENAMES
'IN THE DIRECTORY, INCLUDING HIDDEN, SYSTEM, AND READ-ONLY FILES
'THE FUNCTION IS NON RECURSIVE, I.E., IT DOES NOT SEARCH
'SUBDIRECTORIES UNDERNEATH DIRPATH

'REQUIRES: VB6, BECAUSE IT RETURNS A STRING ARRAY

'EXAMPLE
'Dim sFiles() As String
'Dim lCtr As Long

'sFiles = AllFiles("C:\windows\")
'For lCtr = 0 To UBound(sFiles)
'    Debug.Print sFiles(lCtr)
'Next
'********************************************************

Dim sFile As String
Dim lElement As Long
Dim sAns() As String
ReDim sAns(0) As String

sFile = Dir(DirPath, vbNormal + vbHidden + vbReadOnly + _
   vbSystem + vbArchive)
If sFile <> "" Then
sAns(0) = sFile
    Do
        sFile = Dir
        If sFile = "" Then Exit Do
        lElement = IIf(sAns(0) = "", 0, UBound(sAns) + 1)
        ReDim Preserve sAns(lElement) As String
        sAns(lElement) = sFile
    Loop
End If
AllFiles = sAns
End Function

Public Function APIAllFiles(ByVal DirPath As String) As String()
'***************************************************
'SEE COMMENTS FOR ALLFILES.  PURPOSE AND INSTRUCTIONS ARE
'EXACTLY THE SAME, EXCEPT THIS FILE USES THE WIN32 API
'***************************************************

Dim sFile As String
Dim lElement As Long
Dim sAns() As String
Dim lFirstRet As Long, lNextRet
Dim typFindData As WIN32_FIND_DATA
Dim sTemp As String
Dim lAttr As Long

ReDim sAns(0) As String

If Right(DirPath, 1) = "\" Then DirPath = DirPath & "*.*"

'Get First File
lFirstRet = FindFirstFile(DirPath, typFindData)
If lFirstRet <> -1 Then
    lAttr = typFindData.dwFileAttributes

    'Check if this is a directory.  This is probably slowing down
    'the function.  If you know you won't have subdirectories,
    'or you want to include directories, delete this check

    If Not isDirectory(lAttr) Then

        'strip null terminator
       sAns(0) = StripNull(typFindData.cFileName)
    End If
   
    'Continue searching until all files in directory are found
    Do
        lNextRet = FindNextFile(lFirstRet, typFindData)
        If lNextRet = ERROR_NO_MORE_FILES Or _
           lNextRet = 0 Then Exit Do
        lAttr = typFindData.dwFileAttributes
            'Again, check if its a subdirectory
            If Not isDirectory(lAttr) Then
                lElement = IIf(sAns(0) = "", 0, UBound(sAns) + 1)
                ReDim Preserve sAns(lElement) As String
                sAns(lElement) = StripNull(typFindData.cFileName)
            End If
    Loop
End If

FindClose lFirstRet
APIAllFiles = sAns

End Function

Private Function StripNull(ByVal InString As String) As String

'Input: String containing null terminator (Chr(0))
'Returns: all character before the null terminator

Dim iNull As Integer
If Len(InString) > 0 Then
    iNull = InStr(InString, vbNullChar)
    Select Case iNull
    Case 0
        StripNull = InString
    Case 1
        StripNull = ""
    Case Else
       StripNull = Left$(InString, iNull - 1)
   End Select
End If

End Function

Public Function isDirectory(FileAttr As Long) As Boolean

Dim bAns As Boolean
Dim lDir As Long
Dim lHidden As Long
Dim lSystem As Long
Dim lReadOnly As Long

lDir = FILE_ATTRIBUTE_DIRECTORY
lHidden = FILE_ATTRIBUTE_HIDDEN
lSystem = FILE_ATTRIBUTE_SYSTEM
lReadOnly = FILE_ATTRIBUTE_READONLY
   
isDirectory = FileAttr = lDir Or FileAttr = _
    lDir + lHidden Or FileAttr = lDir + lSystem _
    Or FileAttr = lDir + lReadOnly Or FileAttr = _
    lDir + lHidden + lSystem Or FileAttr = _
    lDir + lHidden + lReadOnly Or FileAttr = _
    lDir + lSystem + lReadOnly Or _
    FileAttr = lDir + lSystem + lHidden + lReadOnly

End Function
0
 
LVL 28

Accepted Solution

by:
AzraSound earned 0 total points
ID: 6480496
Grade me
0
 

Author Comment

by:rtcomp
ID: 6486333
Sorry about that. Very good
0
 
LVL 2

Expert Comment

by:TravisHall
ID: 6486353
Can't somebody tell me what just happened? Did AzraSound really just get a grade of A for a response reading, in its entirety, "Grade me"?

I dearly hope that one of the other responses was from AzraSound by another name, but even so, surely the grade should go to that response, so we all know what the correct response was.
0
 

Expert Comment

by:TonyS020799
ID: 6486508
All,
Apparently, rtcomp did not take the time to award the correct expert who offered the correct response.  For the time being, I am reducing the points here to 0 (we cannot "undo" a grade/answer once a comment has been accepted).  rtcomp, I propose you offer a new question to award points to the expert whose actual answer provided you with the solution you were after.


TonyS
Community Support Moderator @ Experts Exchange
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

Introduction In a recent article (http://www.experts-exchange.com/A_7811-A-Better-Concatenate-Function.html) for the Excel community, I showed an improved version of the Excel Concatenate() function.  While writing that article I realized that no o…
Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now