[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Netresource question visual basic 6

Posted on 2004-11-22
5
Medium Priority
?
962 Views
Last Modified: 2012-06-27
Hello,

I have been using the following module in my prog to map drives, works great.  I recently added a .class for listing out computers on a network.   Class is at bottom.  Getting method or data member not found when trying to map my drives after adding the .class.  HELP!!!




Dim NetR As NetResource    ' NetResouce structure
   Dim ErrInfo As Long        ' Return value from API
   Dim Buffer As String       ' Drive letter assigned to resource
   Dim bufferlen As Long      ' Size of the buffer



ERROR IS HERE! >>>>>>>   NetR.dwScope = RESOURCE_GLOBALNET

   NetR.dwType = RESOURCETYPE_DISK
   NetR.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE
   NetR.dwUsage = RESOURCEUSAGE_CONNECTABLE
   NetR.lpLocalName = vbNullString
   NetR.lpRemoteName = "\\" & Computer & "\C$"










'***************ORIGINAL DRIVE MAPPING MODULE
Public Declare Function OpenProcess Lib "KERNEL32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function GetExitCodeProcess Lib "KERNEL32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Public Declare Sub Sleep Lib "KERNEL32" (ByVal dwMilliseconds As Long)
Const STILL_ACTIVE = &H103
Const PROCESS_QUERY_INFORMATION = &H400


'Constants
Public Const NO_ERROR = 0
Public Const CONNECT_LOCALDRIVE = 256
Public Const CONNECT_REDIRECT = 128
Public Const RESOURCE_GLOBALNET = &H2
Public Const RESOURCETYPE_DISK = &H1
Public Const RESOURCEDISPLAYTYPE_SHARE = &H3
Public Const RESOURCEUSAGE_CONNECTABLE = &H1
Public Const CONNECT_UPDATE_PROFILE = 1

' LOCAL VARIABLES
Public MappedDrive As String

' CUSTOM TYPES
Private Type NetResource
    dwScope As Long
    dwType As Long
    dwDisplayType As Long
    dwUsage As Long
    lpLocalName As String
    lpRemoteName As String
    lpComment As String
    lpProvider As String
End Type

' API DECLARATIONS
Public Declare Function WNetUseConnection Lib "mpr.dll" _
   Alias "WNetUseConnectionA" ( _
   ByVal hwndOwner As Long, _
   ByRef lpNetResource As NetResource, _
   ByVal lpUsername As String, _
   ByVal lpPassword As String, _
   ByVal dwFlags As Long, _
   ByVal lpAccessName As Any, _
   ByRef lpBufferSize As Long, _
   ByRef lpResult As Long) _
   As Long

Public Declare Function WNetCancelConnection2 Lib "mpr.dll" _
   Alias "WNetCancelConnection2A" ( _
   ByVal lpName As String, _
   ByVal dwFlags As Long, _
   ByVal fForce As Long) _
   As Long
'*****************************












'**************CLASS THAT WAS ADDED AND CAUSED PROBLEMS
Option Explicit

Public Enum NetResourceTypes    ' Enum of possible types of NetResource
    Generic = 0
    Domain = 1
    Server = 2
    share = 3
    File = 4
    Group = 5
    Network = 6
    Root = 7
    ShareAdmin = 8
    Directory = 9
    Tree = 10
    NDSContainer = 11
    Printer = &HFF
End Enum

Private mvNetRes As NETRES2
Private mvGotChildren As Boolean
Private mvChildren As NetResources  ' Collection of child containers and disk objects (what you usually get in the Network Neighborhood tree)
Private mvAmRoot As Boolean
Private mvAmPrinter As Boolean

Private Declare Function GlobalAlloc Lib "KERNEL32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "KERNEL32" (ByVal hMem As Long) As Long
Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Declare Function lstrcpyA Lib "KERNEL32" Alias "lstrcpy" (ByVal NewString As String, ByVal OldString As Long) As Long
Private Declare Function WNetOpenEnum Lib "mpr.dll" Alias "WNetOpenEnumA" (ByVal dwScope As Long, ByVal dwType As Long, ByVal dwUsage As Long, lpNetResource As Any, lphEnum As Long) As Long
Private Declare Function WNetEnumResource Lib "mpr.dll" Alias "WNetEnumResourceA" (ByVal hEnum As Long, lpcCount As Long, ByVal lpBuffer As Long, ByRef lpBufferSize As Long) As Long
Private Declare Function WNetCloseEnum Lib "mpr.dll" (ByVal hEnum As Long) As Long

Private Type sNETRESOURCE ' API compatible NETRESOURCE structure
    dwScope As Long       ' All members expressed as Long pointers
    dwType As Long
    dwDisplayType As Long
    dwUsage As Long
    lpLocalName As Long
    lpRemoteName As Long
    lpComment As Long
    lpProvider As Long
End Type
   
Private Type NETRES2 ' VB compatible NETRESOURCE structure
    dwScope As Long  ' Members mapped back to VB datatypes
    dwType As Long
    dwDisplayType As Long
    dwUsage As Long
    lpLocalName As String
    lpRemoteName As String
    lpComment As String
    lpProvider As String
End Type

Private Const RESOURCE_CONNECTED = &H1
Private Const RESOURCE_GLOBALNET = &H2
Private Const RESOURCE_REMEMBERED = &H3
Private Const RESOURCE_CONTEXT = &H5

Private Const RESOURCETYPE_ANY = &H0
Private Const RESOURCETYPE_DISK = &H1
Private Const RESOURCETYPE_PRINT = &H2
Private Const RESOURCETYPE_UNKNOWN = &HFFFF

Private Const RESOURCEUSAGE_CONNECTABLE = &H1
Private Const RESOURCEUSAGE_CONTAINER = &H2
Private Const RESOURCEUSAGE_RESERVED = &H80000000

Private Const GMEM_DDESHARE = &H2000
Private Const GMEM_DISCARDABLE = &H100
Private Const GMEM_DISCARDED = &H4000
Private Const GMEM_FIXED = &H0
Private Const GMEM_INVALID_HANDLE = &H8000
Private Const GMEM_LOCKCOUNT = &HFF
Private Const GMEM_MODIFY = &H80
Private Const GMEM_MOVEABLE = &H2
Private Const GMEM_NOCOMPACT = &H10
Private Const GMEM_NODISCARD = &H20
Private Const GMEM_NOT_BANKED = &H1000
Private Const GMEM_NOTIFY = &H4000
Private Const GMEM_SHARE = &H2000
Private Const GMEM_VALID_FLAGS = &H7F72
Private Const GMEM_ZEROINIT = &H40
Private Const GPTR = (GMEM_FIXED Or GMEM_ZEROINIT)

Private Const ERROR_MORE_DATA = 234

Private Const RESOURCEDISPLAYTYPE_GENERIC = 0
Private Const RESOURCEDISPLAYTYPE_DOMAIN = 1
Private Const RESOURCEDISPLAYTYPE_SERVER = 2
Private Const RESOURCEDISPLAYTYPE_SHARE = 3
Private Const RESOURCEDISPLAYTYPE_FILE = 4
Private Const RESOURCEDISPLAYTYPE_GROUP = 5
Private Const RESOURCEDISPLAYTYPE_NETWORK = 6
Private Const RESOURCEDISPLAYTYPE_ROOT = 7
Private Const RESOURCEDISPLAYTYPE_SHAREADMIN = 8
Private Const RESOURCEDISPLAYTYPE_DIRECTORY = 9
Private Const RESOURCEDISPLAYTYPE_TREE = &HA
Private Const RESOURCEDISPLAYTYPE_NDSCONTAINER = &HB

Private Sub GetPrinters()
' API wrangling...
' Basically the same routine as GetChildren but tweaked to only return printer objects
' It also discards all non-share objects since we only want printers for this enumeration

' Initialise my collection and variables
Dim hEnum As Long, lpBuff As Long
Dim cbBuff As Long, cCount As Long
Dim p As Long, res As Long, i As Long
Dim EnumHTemp As Long
Dim reqBufferSize As Long
Dim nR As sNETRESOURCE  ' API friendly structure
Dim tempRes As NETRES2  ' VB friendly structure
Dim tChild As NetResource

' If this object is the Network root then we need to make a slight adjustment to the starting values
' of our API friendly NETRESOURCE structure
If mvAmRoot Then
    nR.dwUsage = RESOURCEUSAGE_CONNECTABLE
    nR.lpRemoteName = 0
End If

' Open a net enumeration
' Limit enumeration to connectable print resources (i.e. printer objects)
res = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_PRINT, RESOURCEUSAGE_CONNECTABLE, mvNetRes, hEnum)

' Check for errors
If res <> 0 Then
    ' Error returned when trying to open the enumeration
    ' Probably means we don't have access to see its children.
    ' See the MSDN for more details on possible errors.
    ' Currently no trapping is done here and the routine just exits with an empty children collection
    Exit Sub
End If

' Now begin to enumerate the collection
EnumHTemp = hEnum
' Allocate a default buffer for the NETRESOURCE structure returned from the enum routine, say 1K
cbBuff = 1024&
lpBuff = GlobalAlloc(GPTR, cbBuff)
Do
    EnumHTemp = hEnum
    cCount = &HFFFFFFFF ' Number of entries to return from enumeration - &HFFFFFFFF causes all objects to be returned
    res = WNetEnumResource(hEnum, cCount, lpBuff, cbBuff)
    If res = ERROR_MORE_DATA Then
        ' The enumeration has reported that the lpBuff is not big enough to hold all of the information in the
        ' NETRESOURCE structure. cbBuff has been updated to hold the required amount of space.
        GlobalFree lpBuff   ' Free the memory we're using for the current small buffer
        lpBuff = GlobalAlloc(GPTR, cbBuff)  ' Allocate a new space of the size requested by the enumeration
    Else
        If res = 0 Then     ' No error
            p = lpBuff
            ' cCount holds the number of NETRESOURCE structures returned in this pass
            ' (The enumeration returns as many as will fit into the buffer)
            For i = 1 To cCount ' Loop through the buffer, tackling each structure in turn
                CopyMemory nR, ByVal p, LenB(nR)    ' Copy the block of memory representing the structure into a local API friendly NETRESOURCE structure
                p = p + LenB(nR)    ' Step forward in the buffer by the length of the copied structure
                If nR.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE Then
                    tempRes.dwDisplayType = nR.dwDisplayType
                    tempRes.dwScope = nR.dwScope
                    tempRes.dwType = nR.dwType
                    tempRes.dwUsage = nR.dwUsage
                    tempRes.lpComment = lStrCpy(nR.lpComment)
                    tempRes.lpLocalName = lStrCpy(nR.lpLocalName)
                    tempRes.lpProvider = lStrCpy(nR.lpProvider)
                    tempRes.lpRemoteName = lStrCpy(nR.lpRemoteName)
                    Set tChild = New NetResource
                    tChild.NRStruct = tempRes
                    tChild.IsPrinter = True ' I know this is a bit of a fudge, but I didn't think it worth the effort to write polymorphic classes for such a small matter
               
                    mvChildren.Add tChild
                End If
            Next
        End If
    End If
Loop Until cCount = 0
' Close the enum
WNetCloseEnum hEnum
' Free the memory
GlobalFree lpBuff

End Sub

Friend Property Let IsPrinter(pVal As Boolean)
mvAmPrinter = pVal
End Property

Private Function lStrCpy(lStrPointer As Long) As String
Dim TString As String
TString = String(255, Chr$(0))
lstrcpyA TString, lStrPointer
lStrCpy = Left(TString, InStr(TString, Chr$(0)) - 1)
End Function

Public Property Get Children() As NetResources
If Not mvGotChildren Then GetChildren
Set Children = mvChildren
End Property



Public Property Get Comment() As String
Comment = mvNetRes.lpComment
End Property

Private Sub GetChildren()
' API wrangling...

' Initialise my collection and variables
Set mvChildren = New NetResources
Dim hEnum As Long, lpBuff As Long
Dim cbBuff As Long, cCount As Long
Dim p As Long, res As Long, i As Long
Dim EnumHTemp As Long
Dim reqBufferSize As Long
Dim nR As sNETRESOURCE  ' API friendly structure
Dim tempRes As NETRES2  ' VB friendly structure
Dim tChild As NetResource

' If this object is the Network root then we need to make a slight adjustment to the starting values
' of our API friendly NETRESOURCE structure
If mvAmRoot Then
    nR.dwUsage = RESOURCEUSAGE_CONNECTABLE
    nR.lpRemoteName = 0
End If

' Open a net enumeration
res = WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0, mvNetRes, hEnum)

' Check for errors
If res <> 0 Then
    ' Error returned when trying to open the enumeration
    ' Probably means we don't have access to see its children.
    ' See the MSDN for more details on possible errors.
    ' Currently no trapping is done here and the routine just exits with an empty children collection
    Exit Sub
End If

' Now begin to enumerate the collection
EnumHTemp = hEnum
' Allocate a default buffer for the NETRESOURCE structure returned from the enum routine, say 1K
cbBuff = 1024&
lpBuff = GlobalAlloc(GPTR, cbBuff)
Do
    EnumHTemp = hEnum
    cCount = &HFFFFFFFF ' Number of entries to return from enumeration - &HFFFFFFFF causes all objects to be returned
    res = WNetEnumResource(hEnum, cCount, lpBuff, cbBuff)
    If res = ERROR_MORE_DATA Then
        ' The enumeration has reported that the lpBuff is not big enough to hold all of the information in the
        ' NETRESOURCE structure. cbBuff has been updated to hold the required amount of space.
        GlobalFree lpBuff   ' Free the memory we're using for the current small buffer
        lpBuff = GlobalAlloc(GPTR, cbBuff)  ' Allocate a new space of the size requested by the enumeration
    Else
        If res = 0 Then     ' No error
            p = lpBuff
            ' cCount holds the number of NETRESOURCE structures returned in this pass
            ' (The enumeration returns as many as will fit into the buffer)
            For i = 1 To cCount ' Loop through the buffer, tackling each structure in turn
                CopyMemory nR, ByVal p, LenB(nR)    ' Copy the block of memory representing the structure into a local API friendly NETRESOURCE structure
                p = p + LenB(nR)    ' Step forward in the buffer by the length of the copied structure
                tempRes.dwDisplayType = nR.dwDisplayType    ' Begin copying the members of the API friendly structure to the VB friendly structure
                tempRes.dwScope = nR.dwScope
                tempRes.dwType = nR.dwType
                tempRes.dwUsage = nR.dwUsage
                tempRes.lpComment = lStrCpy(nR.lpComment)   ' String copies accomplished by using the lStrCpy routine
                tempRes.lpLocalName = lStrCpy(nR.lpLocalName)
                tempRes.lpProvider = lStrCpy(nR.lpProvider)
                tempRes.lpRemoteName = lStrCpy(nR.lpRemoteName)
                Set tChild = New NetResource    ' Create the new NetResource object that will be the new child
                tChild.NRStruct = tempRes   ' Pass the current VB friendly NETRESOURCE structure to tbe force populate method of the NetResource object
                mvChildren.Add tChild   ' Add the new object to my children collection
            Next
        End If
    End If
Loop Until cCount = 0
' Close the enum
WNetCloseEnum hEnum
' Free the memory
GlobalFree lpBuff

' In order to distinguish printers from other shares we need to enumerate them separately
GetPrinters

mvGotChildren = True

End Sub

Public Property Get LocalName() As String
LocalName = mvNetRes.lpLocalName

End Property


Friend Property Let NRStruct(RHS As NETRES2)
' Private force populate routine
' When a NetResource object it defaults to being the network root object
' The only way to change this is to call this routine and pass a VB friendly NETRES2 NETRESOURCE structure
' When this function is called correctly it populates the data for this NetResource and forces it to act as a child rather than
' a network root.
' When compiled as a COM DLL this function will not be visible to the user - it's intended for internal use only
mvNetRes = RHS
mvAmRoot = False
End Property



Public Property Get Provider() As String
Provider = mvNetRes.lpProvider
End Property

Public Property Get RemoteName() As String
RemoteName = mvNetRes.lpRemoteName
End Property


Public Property Get ResourceType() As NetResourceTypes
If Not mvAmPrinter Then ResourceType = mvNetRes.dwDisplayType Else ResourceType = Printer

End Property

Public Property Get ResourceTypeName() As String
' Provides a friendly name for the resource type as an alternative to using the enumerated "ResourceType" property
' This can be used to quicky bind NetResource objects to named images in an imagelist control (for example)
If mvAmPrinter Then
    ResourceTypeName = "Printer"
    Exit Property
End If
Select Case mvNetRes.dwDisplayType
    Case RESOURCEDISPLAYTYPE_GENERIC
        ResourceTypeName = "Generic"
    Case RESOURCEDISPLAYTYPE_DOMAIN
        ResourceTypeName = "Domain"
    Case RESOURCEDISPLAYTYPE_SERVER
        ResourceTypeName = "Server"
    Case RESOURCEDISPLAYTYPE_SHARE
        ResourceTypeName = "Share"
    Case RESOURCEDISPLAYTYPE_FILE
        ResourceTypeName = "File"
    Case RESOURCEDISPLAYTYPE_GROUP
        ResourceTypeName = "Group"
    Case RESOURCEDISPLAYTYPE_NETWORK
        ResourceTypeName = "Network"
    Case RESOURCEDISPLAYTYPE_ROOT
        ResourceTypeName = "Root"
    Case RESOURCEDISPLAYTYPE_SHAREADMIN
        ResourceTypeName = "AdminShare"
    Case RESOURCEDISPLAYTYPE_DIRECTORY
        ResourceTypeName = "Directory"
    Case RESOURCEDISPLAYTYPE_TREE
        ResourceTypeName = "Tree"
    Case RESOURCEDISPLAYTYPE_NDSCONTAINER
        ResourceTypeName = "NDSContainer"
End Select
End Property

Public Property Get ShortName() As String
' Return just the final part of the object's name (rather than a fully qualified path or context)
Dim i As Integer
i = InStrRev(mvNetRes.lpRemoteName, "\")
ShortName = Right(mvNetRes.lpRemoteName, Len(mvNetRes.lpRemoteName) - i)
End Property


Private Sub Class_Initialize()
mvAmRoot = True
End Sub


Private Sub Class_Terminate()
Set mvChildren = Nothing
End Sub



0
Comment
Question by:bluedragon99
  • 3
5 Comments
 
LVL 7

Expert Comment

by:jacobhoover
ID: 12650254
You have:
Private Type NetResource
...

In your module.. So this type is private.

Change it to Public and all should be well.

Jake
0
 
LVL 7

Expert Comment

by:jacobhoover
ID: 12650370
Hmm,
  after further review... you have more code missing and a reference to what seems to be as NetResource as a type AND a class.  Also, what is calling NRStruct of the problematic class, as the private type is not going to be accessable from the outside world (IE, outside the COM DLL)

Jake
0
 
LVL 15

Expert Comment

by:Ralf Klatt
ID: 12650430
Hi,

Please give us the exact error message you're receiving ... meaning, if jacobhoover is right, you should have had an "User-defined type not defined" error ... if there's any other error message ... please let us know!


Best regards,
Raisor
0
 
LVL 7

Accepted Solution

by:
jacobhoover earned 2000 total points
ID: 12650490
No,
What I THINK is happening is:
ERROR IS HERE! >>>>>>>   NetR.dwScope = RESOURCE_GLOBALNET

As NetR is defined as NetResource, which appears to be the name of the Public Class in the DLL and is also the name of the Private type in your module.  In this case, you are treating it as the type, however I am 99% sure VB is seeing it as the class and would be giving you a "Method or data member not found."

Also, I noted that in order for me to get your code to enumerate a remote device I did not need to have:
 NetR.lpRemoteName = "\\" & Computer & "\C$"
Rather I used.
 NetR.lpRemoteName = "\\" & Computer

Then w/ a little work I was able to get the internal collection populated w/ a list of available shares on the remote machine.

Jake
0
 
LVL 1

Author Comment

by:bluedragon99
ID: 12651037
Got it guys thanks!

Netresource type was defined in the class and in my drive mapping module.  Class was taking precedence as jacobhoover mentioned.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Computer science students often experience many of the same frustrations when going through their engineering courses. This article presents seven tips I found useful when completing a bachelors and masters degree in computing which I believe may he…
In real business world data are crucial and sometimes data are shared among different information systems. Hence, an agreeable file transfer protocol need to be established.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
Screencast - Getting to Know the Pipeline

829 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