Click here to Skip to main content
Click here to Skip to main content

Enumerating Network Resources

By , 27 Feb 2004
 

Introduction

I'm very new to C# as a programming language and to .NET as a framework. Coming as I did from a C++ and MFC background I researched the alternatives and hinted to my family that a copy of Tom Archers 'Inside C#' (2nd edition) would be a much appreciated Christmas present. The hints were taken and it arrived in my Christmas stocking. A good read and very well worth the money that I don't offically know about :). Having read the book from cover to cover it was time to write some real C# code. But I'm of the school of thought that says that one cannot truly learn a new programming language by using examples targetted at just one or another feature of the new language. I need a real project. Otherwise, if I attempt something and it doesn't work the way I imagine it should it's all too easy to write it off. A real project presents challenges that must be solved before the project can be said to be complete.

The Project

I chose a project that's pretty much going to be out of date in maybe a years time, probably rather less. It's a SETI monitor that automatically discovers computers on my local network and monitors the progress of instances of SETI running on each computer. This article doesn't present that project (though a future article might).

Instead, this article focusses on a class I wrote as part of the project to enumerate network resources. In Win32 you do this by using the WNetOpenEnum() API followed by (probably) multiple calls to the WNetEnumResource() API.

A not so quick search of the .NET documentation didn't reveal any classes implementing this functionality so it was time to write my own. Bear in mind that this code was written by a veteran C++ programmer trying to move to C# :)

Moving a C++ function to C#

I have written code using the WNetOpenEnum() and WNetEnumResource() API's many times in the past, always in C++. So I was starting from the standpoint of having written working code but without necessarily understanding all the nuances of the API. After all, if it works following the MSDN examples tailored to my needs one moves on to other stuff right?

So I started with working C++ code. I won't present the code here. But let's discuss the API's. The first API is WNetOpenEnum(). The C/C++ prototype looks like this.

DWORD WNetOpenEnum(
    DWORD dwScope,                // scope of enumeration
    DWORD dwType,                 // resource types to list
    DWORD dwUsage,                // resource usage to list
    LPNETRESOURCE lpNetResource,  // resource structure
    LPHANDLE lphEnum              // enumeration handle buffer
);
I won't go into all the details of the various parameters but I'll pass lightly over them. The scope parameter specifies whether you want to enumerate global resources, remembered resources and suchlike. The type parameter lets you restrict enumerated resources to disk, print or all. Usage lets you specify such things as containers. (See the MSDN documentation for full details).

The lphEnum is a pointer to a handle to an enumeration context which is used in subsequent calls to WNetEnumResource().

That leaves the lpNetResource parameter.

All the parameters apart from the lpNetResource parameter map directly onto C# datatypes. The lpNetResource parameter doesn't. So let's look at the C/C++ definition of that type.

The NETRESOURCE structure

typedef struct _NETRESOURCE { 
    DWORD  dwScope; 
    DWORD  dwType; 
    DWORD  dwDisplayType; 
    DWORD  dwUsage; 
    LPTSTR lpLocalName; 
    LPTSTR lpRemoteName; 
    LPTSTR lpComment; 
    LPTSTR lpProvider; 
} NETRESOURCE; 

All of the members map onto a C# datatype. DWORD maps on the C# uint type and LPTSTR maps onto the string type. So far so good.

So let's see what a C# definition of a NETRESOURCE structure might look like.

[StructLayout(LayoutKind.Sequential)]
private class NETRESOURCE 
{
    public ResourceScope       dwScope = 0;
    public ResourceType        dwType = 0;
    public ResourceDisplayType dwDisplayType = 0;
    public ResourceUsage       dwUsage = 0;
    public string              lpLocalName = null;
    public string              lpRemoteName = null;
    public string              lpComment = null;
    public string              lpProvider = null;
};
This is a literal copy of the NETRESOURCE structure from the C/C++ header file with the syntax massaged to make it digestible to the C# compiler. Well not quite. Each DWORD member has been changed to an enum type, where the enum values are defined elsewhere within the class. The enum values are in turn literal copies of the relevant C/C++ values massaged to make them digestible to the C# compiler. I did it this way for two reasons. The first is that I believe even the original C++ structure should have been defined in this way. Changing the DWORD's into enum's buys some compile time parameter checking for free. The second reason is that (at least in Visual Studio), Intellisense will kick in and help me remember the constants.

The WNetOpenEnum() function

The definition of the WNetOpenEnum() API, for C#, looks like this,
[DllImport("Mpr.dll", EntryPoint="WNetOpenEnumA", 
           CallingConvention=CallingConvention.Winapi)]
private static extern ErrorCodes WNetOpenEnum(ResourceScope dwScope, 
                                              ResourceType dwType, 
                                              ResourceUsage dwUsage, 
                                              NETRESOURCE p,
                                              out IntPtr lphEnum);
That's pretty straightforward. Simply set up a call using the various enum values for the type of enumeration you want, pass it an instance of the NETRESOURCE structure and a reference to a place to store the returned enumeration handle. Calling code might look like this:
IntPtr     handle = IntPtr.Zero;
ErrorCodes result;

result = WNetOpenEnum(ResourceScope.RESOURCE_GLOBALNET, ResourceType.RESOURCETYPE_ANY, 
                      ResourceUsage.RESOURCEUSAGE_ALL, pRsrc, out handle);

The WNetEnumResource() function

Now we've got a handle to an open enumerator we use that handle to request information from the OS.
[DllImport("Mpr.dll", EntryPoint="WNetEnumResourceA", 
           CallingConvention=CallingConvention.Winapi)]
private static extern ErrorCodes WNetEnumResource(IntPtr hEnum, 
                                                  ref uint lpcCount,
                                                  IntPtr buffer, 
                                                  ref uint lpBufferSize);
This is where things get interesting. If you have another look at the NETRESOURCE structure you'll see that it contains 4 pointers to strings. An obvious questions is where do those pointers point? In other words, where is the memory allocated? A few moments thought reveals that they can't be pointing at strings inside the OS because in all likelihood those strings are in someone elses memory space. The API has to copy the strings into memory visible to the calling process. Therefore, the memory into which the strings are copied must be allocated by the calling process. However the documentation says nothing about how large each string buffer should be or even if we should point each pointer at a buffer allocated in our memory space. A close reading of the MSDN documentation for the WNetEnumResource() reveals this in the remarks.

An application cannot set the lpBuffer parameter to NULL and retrieve the required buffer size from the lpBufferSize parameter. Instead, the application should allocate a buffer of a reasonable size (16 kilobytes is typical) and use the value of lpBufferSize for error detection.

Aha! Obviously the WNetEnumResource API reserves the first few bytes of the memory buffer for an instance of the NETRESOURCE structure and copies the strings into the same buffer after that structure. So we're expected to allocate a buffer large enough to hold the NETRESOURCE structure and all 4 strings. In C++ this is trivial. And doubtless, as I become more proficient with C# and the .NET Framework, it'll become trivial there too :)

Incidentally, this also reveals how old these API's are. I'm sure the structure would have used BSTR's to solve the memory allocation problem had they existed at the time this structure was defined.

A hidden gotcha

Another close reading of the documentation for WNetEnumResource() says that if you set the lpCount to X the function will return X results if they will fit into the buffer. If not it will return as many results as will fit in the buffer and set the value pointed at by lpCount to the number of returned results. But in practice it doesn't seem to work that way. All my tests in C++ return just 1 result per call regardless of how large the buffer is and what I specify as the desired count. *shrug*

The WNetCloseEnum() function

As you'd expect, having opened a handle and used it, you're required to close it when you've done with it. That's done with the WNetCloseEnum() API.
[DllImport("Mpr.dll", EntryPoint="WNetCloseEnum", 
           CallingConvention=CallingConvention.Winapi)]
private static extern ErrorCodes WNetCloseEnum(IntPtr hEnum);

Putting it all together

So we've had a look at the 3 API's and the structure we need to enumerate servers on our local network. Here's the enumeration function itself:
private void EnumerateServers(
                NETRESOURCE pRsrc, 
                ResourceScope scope, 
                ResourceType type, 
                ResourceUsage usage, 
                ResourceDisplayType displayType)
{
    uint        bufferSize = 16384;
    IntPtr      buffer  = Marshal.AllocHGlobal((int) bufferSize);
    IntPtr      handle = IntPtr.Zero;
    ErrorCodes  result;
    uint        cEntries = 1;

    result = WNetOpenEnum(scope, type, usage, pRsrc, out handle);

    if (result == ErrorCodes.NO_ERROR)
    {
        do
        {
            result = WNetEnumResource(handle, ref cEntries, buffer, ref bufferSize);

            if (result == ErrorCodes.NO_ERROR)
            {
                Marshal.PtrToStructure(buffer, pRsrc);

                if (pRsrc.dwDisplayType == displayType)
                    aData.Add(pRsrc.lpRemoteName);

                //  If this is a container resource recursively call ourselves to 
                //  enumerate the contents...
                if ((pRsrc.dwUsage & ResourceUsage.RESOURCEUSAGE_CONTAINER) == 
                                     ResourceUsage.RESOURCEUSAGE_CONTAINER)
                    EnumerateServers(pRsrc, scope, type, usage, displayType);
            }
            else if (result != ErrorCodes.ERROR_NO_MORE_ITEMS)
                break;
        } while (result != ErrorCodes.ERROR_NO_MORE_ITEMS);

        WNetCloseEnum(handle);
    }

    Marshal.FreeHGlobal((IntPtr) buffer);
}
This is almost trivial. We pass a NETRESOURCE structure and a bunch of constants to the function. We then open the enumeration and if that succeeds we go into a loop calling WNetEnumResource() for each network resource. For each resource whose type matches the type passed as a parameter we add the remote name member of the structure to an array. For each resource which has the ResourceUsage.RESOURCEUSAGE_CONTAINER bit set we recursively call the function.

But wait a minute! What's with the Marshal.AllocHGlobal() call? That's to allocate a block of memory to serve as the buffer which the WNetEnumResource() API will treat as a NETRESOURCE structure followed by buffer space for the strings.

When we get the buffer back after the call we use Marshal.PtrToStructure() to copy the NETRESOURCE portion of the buffer into the structure instance passed to the function. When the copy is done the string members of the structure still point at the strings allocated within the buffer. I struggled mightily with this (doubtless because of my C++ background). It took seeming ages to understand that even with the unsafe keyword bracketing code the compiler wasn't about to let me simply cast the buffer into a NETRESOURCE structure without some .NET Framework intervention. My thanks go to Heath Stewart for pointing me in the right direction.

Other things about the class

Because the class is used to enumerate a list of servers it makes sense for it to implement the IEnumerable interface to allow it to be used inside a foreach statement. I used a trick Tom Archer mentions in his book. Because the class uses an ArrayList to store the list of enumerated servers and that class already implements IEnumerable my GetEnumerator() implementation simply returns the enumerator for the ArrayList.
public IEnumerator GetEnumerator()
{
    return aData.GetEnumerator();
}
What could be simpler than that?

The enumerator returns strings, so one might use it like this.

ServerEnum servers = new ServerEnum(ResourceScope.RESOURCE_GLOBALNET,
                                    ResourceType.RESOURCETYPE_DISK, 
                                    ResourceUsage.RESOURCEUSAGE_ALL, 
                                    ResourceDisplayType.RESOURCEDISPLAYTYPE_SHARE);

foreach (string s1 in servers)
    Console.WriteLine(s1);
Which example would enumerate all shares on the network. If the second parameter were changed to ResourceType.RESOURCETYPE_PRINT a list of all printer shares would be returned. The sample project download is compiled to show a list of servers on the network. So the relevant code looks like this.
ServerEnum servers = new ServerEnum(ResourceScope.RESOURCE_GLOBALNET,
                                    ResourceType.RESOURCETYPE_DISK, 
                                    ResourceUsage.RESOURCEUSAGE_ALL, 
                                    ResourceDisplayType.RESOURCEDISPLAYTYPE_SERVER);

foreach (string s1 in servers)
    Console.WriteLine(s1);

Control of enumerated results

The bunch of constants that are passed to the EnumerateServers function are used for fine control of the output. The following tables are from the MSDN Library April 2000.

The ResourceScope constants and their meanings are:

Value Meaning
RESOURCE_CONNECTED Enumerate currently connected resources. The dwUsage member cannot be specified.
RESOURCE_GLOBALNET Enumerate all resources on the network. The dwUsage member is specified.
RESOURCE_REMEMBERED Enumerate remembered (persistent) connections. The dwUsage member cannot be specified.

The ResourceType constants are:

Value Meaning
RESOURCETYPE_ANY All resources.
RESOURCETYPE_DISK Disk resources.
RESOURCETYPE_PRINT Print resources.

The ResourceUsage constants are:

Value Meaning
RESOURCEUSAGE_CONNECTABLE The resource is a connectable resource; the name pointed to by the lpRemoteName member can be passed to the WNetAddConnection() function to make a network connection.
RESOURCEUSAGE_CONTAINER The resource is a container resource; the name pointed to by the lpRemoteName member can be passed to the WNetOpenEnum() function to enumerate the resources in the container.

And, finally, the ResourceDisplayType constants are:

Value Meaning
RESOURCEDISPLAYTYPE_DOMAIN The object should be displayed as a domain.
RESOURCEDISPLAYTYPE_SERVER The object should be displayed as a server.
RESOURCEDISPLAYTYPE_SHARE The object should be displayed as a share.
RESOURCEDISPLAYTYPE_GENERIC The method used to display the object does not matter.

The last set of constants, ResourceDisplayType are confusing. The documentation seems to say that it's a hint as to how to display the data. But it actually seems to behave as a filter.

You apply various combinations of these constants to filter the results returned by the network enumerator. For example, if all you're interested in is a list of servers on the network you'd use ResourceScope.RESOURCE_GLOBALNET, ResourceType.RESOURCETYPE_ANY, ResourceUsage.RESOURCEUSAGE_CONTAINER and ResourceDisplayType.RESOURCEDISPLAYTYPE_SERVER.

Note that the class presented in the download includes some constants that aren't documented in MSDN but that are present in the C++ header files. In particular there are many more constants defined for the ResourceDisplayType than MSDN documents. On my system most of them result in nothing being returned at all, but then this is my system, I have a workgroup, not a domain or an Active Directory. I included them for the sake of completeness.

Acknowledgements

I'd like to thank Marc Clifton for reviewing this article for me. As it was my first C# article I was somewhat nervous about posting it so I chose to ask an MVP for review and advice. Marc was very helpful and patient.

History

28 February 2004 - Initial version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Rob Manderson
United States United States
Member
I've been programming for 35 years - started in machine language on the National Semiconductor SC/MP chip, moved via the 8080 to the Z80 - graduated through HP Rocky Mountain Basic and HPL - then to C and C++ and now C#.
 
I used (30 or so years ago when I worked for Hewlett Packard) to repair HP Oscilloscopes and Spectrum Analysers - for a while there I was the one repairing DC to daylight SpecAns in the Asia Pacific area.
 
Afterward I was the fourth team member added to the Australia Post EPOS project at Unisys Australia. We grew to become an A$400 million project. I wrote a few device drivers for the project under Microsoft OS/2 v 1.3 - did hardware qualification and was part of the rollout team dealing directly with the customer.
 
Born and bred in Melbourne Australia, now living in Scottsdale Arizona USA, became a US Citizen on September 29th, 2006.
 
I work for a medical insurance broker, learning how to create ASP.NET websites in VB.Net and C#. It's all good.
 
Oh, I'm also a Kentucky Colonel. http://www.kycolonels.org

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionFAT vs NTFSmemberbaruchl5 Dec '12 - 15:57 
Dear Rob,
thanks for the great article.
 
I know it's very old, but only now I have come across this article.
 
I'm using the code to enumerate all the mapped drives I have (Win7), and I face the following issue - I have 2 mapped drives, I which maps to a FAT drive format, and O to a NTFS drive format.
 
It seems like your code will return only the FAT drive, and completely disregard the NTFS drive.
 
Any way I can do it? I'm not a C++ or Win API techie, so any help is appreciated.
 
Thanks,
Busi
Busi

QuestionHow to pop-up connect to dialog box in C#memberjdkulkarni17 Mar '08 - 23:14 
Can you please tell me how to pop up connect as dialog box to change user credentials?
 
Regards
Jayant
Generalspeed issuesmembergargamehl26 Mar '07 - 13:34 
When I enumerate all my systems, it seems to take a while to do it. are there any ways to speed up the search or is this a limitation of the WNet Functions?
GeneralRe: speed issuesmemberthany.org13 Feb '08 - 2:14 
I ran into the same problem. Especially workgroups that don't have a browse master (or one that's offline) and browsable computers that aren't responding. Those kind of (semi-)unreachable resources just keep waiting until the WNet-function times out, with that timeout being 30 seconds or so.
 
If only there were a function to set the timeout to like 2 seconds. Because practically a server that doesn't respond within 2 seconds, can be considered either offline or way to slow to browse in the first place.
 
--
Thany

QuestionIs there a way to detect Network Printers' IP addresses?memberJan Palmer25 Dec '06 - 21:52 
the program encountered an infinite loop on this line of code:
if (result == ErrorCodes.NO_ERROR){
do{ result = WNetEnumResource(handle, ref cEntries, buffer, ref bufferSize);
if (result == ErrorCodes.NO_ERROR){
Marshal.PtrToStructure(buffer, pRsrc);
if (pRsrc.dwDisplayType == displayType)
aData.Add(pRsrc.lpRemoteName);
if ((pRsrc.dwUsage & ResourceUsage.RESOURCEUSAGE_CONTAINER) == ResourceUsage.RESOURCEUSAGE_CONTAINER)
EnumerateServers(pRsrc, scope, type, usage, displayType);
}
 

.....
 

I have been trying to solve on how to detect IP addresses based on my installed printer drivers around my network but I am getting frustrated each day..heheh.. Win32_Printer, Win32_NetworkAdapter and Win32_TCPIPPrinter failed to get the information that I want..
 
if you're kind enough share your knowledge to email it to me at janverge@gmail.com
 
I would prefer your solution to be in C#
 

thanks again..
 
Merry Christmas

 
nice one..

General.NET 2.0 has 5000+ classes [modified]membergiddy_guitarist25 Aug '06 - 21:41 
um... .NET 2.0 has 5000+ classes .. this kinda thing should be in one of the classes...
 
System.Net( net 2.0) .. could some one help me.. .?? dont know how to use 'em
 
but excellent article i MUST say.. quite well written.. unlike some crappy uncommented code snippets i've found so far that claim to be articles Laugh | :laugh: Laugh | :laugh:
 
if i dont find a pure C# way of doing this i'll have to go your way....
 
Gideon
 

 
-- modified at 3:42 Saturday 26th August, 2006
GeneralGreat and helpful ArticlememberQuartz...27 Jun '06 - 11:01 

You might like to see a beautiful implementation of your NETRESOURCE class
 
Here[^]
 
thanks for sharing
Raj
 

Rule # 17: Omit Needless Words - Strunk, William, Jr.
-------------------------------------------------------------
Universal DBA | Ajax Rating

NewsHere is the C++ eqivelent in code project i found itmemberhaitham hamed housin29 May '06 - 8:00 
http://www.codeproject.com/internet/ipaddress.asp[^]
GeneralRe: Here is the C++ eqivelent in code project i found itmemberAndreas Saurwein Franci Gonçalves18 Jul '08 - 4:59 
One really should be required two things to program: 1) a phsychologial fitness exam and 2) mental maturity
 

Leon[^] - Enterprise Anti-Spam Server

GeneralAll Read This Article , Simple and Do the same job from June 8, 2001memberhaitham hamed housin28 Apr '06 - 14:20 
see the simple with no much talking
http://www.codeguru.com/Cpp/I-N/network/networkinformation/article.php/c5455[^]
 
there is also an article in codeproject but i don't find it now who find it
plz put it here and as soon i get i will
 
i belive in KISS
KEEP IT SIMPLE STUPIT
so that
YOU CAN CAN THE CAN BUT THE CAN CANT CAN YOU
 
-- modified at 20:21 Friday 28th April, 2006
Generaldosn't retrive all IP'S in LAN Like NetCut Uselessmemberhaitham hamed housin28 Apr '06 - 13:24 
0
 
i belive in KISS
KEEP IT SIMPLE STUPIT
so that
YOU CAN CAN THE CAN BUT THE CAN CANT CAN YOU
GeneralRe: dosn't retrive all IP'S in LAN Like NetCut UselessprotectorRob Manderson28 Apr '06 - 13:30 
Never claimed it did!
 
Rob Manderson
 
I'm working on a version for Visual Lisp++
 
My blog http://blogs.wdevs.com/ultramaroon/[^]

GeneralRe: dosn't retrive all IP'S in LAN Like NetCut Uselessmemberhaitham hamed housin28 Apr '06 - 14:25 
i ask u but u didn't answer so u claimed
 
i belive in KISS
KEEP IT SIMPLE STUPIT
so that
YOU CAN CAN THE CAN BUT THE CAN CANT CAN YOU
GeneralDose The Code retrive all IP's Like NetCut plz answermemberhaitham hamed housin27 Apr '06 - 11:26 
Dose The Code retrive all IP's Like NetCut
Dose The Code retrive all IP's Like NetCut
Dose The Code retrive all IP's Like NetCut
 
i belive in KISS
KEEP IT SIMPLE STUPIT
so that
YOU CAN CAN THE CAN BUT THE CAN CANT CAN YOU
Generalevery system in a lan.....membersendmadhavan7 Mar '06 - 1:27 
hey,
will ur program find every system in the lan or is it for enumerating resource only within a domain
GeneralRe: every system in a lan.....memberhaitham hamed housin2 May '06 - 9:46 
no it dosn't only in your workgroup
 
i belive in KISS
KEEP IT SIMPLE STUPIT
so that
YOU CAN CAN THE CAN BUT THE CAN CANT CAN YOU
GeneralRe: every system in a lan.....membergargamehl26 Mar '07 - 13:33 
I got it to enumerate all machines on our system including the NAS.
Generalfind domains in a lanmembersendmadhavan12 Feb '06 - 17:35 
Hii
 
I am new to c#...So can you please tell me how can i find all the domains present in my lan and find the systems present under it...thanks in advance
GeneralRe: find domains in a lanmemberhaitham hamed housin2 May '06 - 9:50 
no it dosn't only in your workgroup
 
i belive in KISS
KEEP IT SIMPLE STUPIT
so that
YOU CAN CAN THE CAN BUT THE CAN CANT CAN YOU
GeneralPerfect codes for me!memberRiverwayRun12 May '05 - 9:12 
Thank you so much Rob! It works perfectly for me!
 
But I have a question: in addtion to enumeration, we need search for computers. For example, in Windows operation system, if you click "Search for comptuers" in "My neighbourhood", then you can input something like: "pc" and click "search" button, then every computer starts with "pc" can be listed. I spent long time to search the internet, but couldn't find a way to implement this through code. Please help me!
 

GeneralRe: Perfect codes for me!protectorRob Manderson13 May '05 - 13:57 
I'd imagine the way you'd achieve that would be to enumerate all computers on the network and use some kind of filter mechanism on the enumerated list. I don't think the Win32 API implements a 'search' mechanism directly.
 
Rob Manderson
 
I'm working on a version for Visual Lisp++
 
My blog http://blogs.wdevs.com/ultramaroon/[^]

GeneralHimemberThe illiterate3 Nov '04 - 0:57 
Smile | :) Great Article! I am greatful to you,but I have not learned VC++ as such
so I had difficulty in understanding
 
public enum ResourceUsage
{
RESOURCEUSAGE_CONNECTABLE = 0x00000001,Confused | :confused:
RESOURCEUSAGE_CONTAINER = 0x00000002,Confused | :confused:
RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004,
RESOURCEUSAGE_SIBLING = 0x00000008,
RESOURCEUSAGE_ATTACHED = 0x00000010,
RESOURCEUSAGE_ALL = (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED),These are I suppose the MACROS
};
To be Specific I could not understand "0x00000001",and So on.....
 
Kindly Can U Explain
 
Regds
Illiterate

GeneralConnecting to Network DrivememberSameers (theAngrycodeR )2 Nov '04 - 13:25 
Nice code. I have a question. What If I want to access some network location through the code? That location requires authentication (username and pwd). The scenario is, I have a windows service which collect different files from different locations (including different network and local folders). The network folders requires user to provide username and pwd. I tried to temporarily add that network location as network drive, accessed the folder and then removed that drive. That worked fine in windows application but when accessing through the service, I receive this error.
 
"A specified logon session does not exist. It may already have been terminated."
 
I used the WNetAddConnection2 API to map the network drive. Can u give me any idea that how can I get rid of this error?
 
Thanks,

GeneralRe: Connecting to Network DrivememberThe illiterate3 Nov '04 - 1:02 
Sameer Although Not Related but I have built an application which is
>Service/Memory Monitor
It works fine for the Local system,But I would like to monitor Other computers in the Network..how can I do that
 
Regds
illiterate
GeneralRe: Connecting to Network DrivememberSameers (theAngrycodeR )3 Nov '04 - 6:31 
Hello,
 
I am sorry, I may not be able to help you in this regard. I myself is fighting with a problem in accessing network folders from my windows service but getting some lack of privilages error.
 
I believe that for this you need to improve the privilages of your service and rest is ur code. I got a tip of using things in this way.
 
LogonUser
ImpersonateLoggedOnUser
RevertToSelf

Means logon user with sufficient privilages, then impersonate user and do your work and then finaly revert things you did before. Above listed three lines are the API names you can use for this task. I am not sure if this work as I myself have not tested it. Lets test both of us and see what we get.
 
Best wishes,
 
Sameers (theAngrycodeR)
http://www.theangrycoder.com

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 28 Feb 2004
Article Copyright 2004 by Rob Manderson
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid