?
Solved

Local shares and converting UNC to local path

Posted on 1999-08-02
30
Medium Priority
?
476 Views
Last Modified: 2008-02-20
Hello,
1) Anybody can tell me how can I have the list of all local shares (under NT and 9x)?
2) Anybody can tell me how to convert a UNC path to local path ?

Thanks;
0
Comment
Question by:curso
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 16
  • 11
  • 2
  • +1
30 Comments
 

Author Comment

by:curso
ID: 1201541
Edited text of question.
0
 
LVL 6

Expert Comment

by:MichaelS
ID: 1201542
It's no problem in the NT, but 9x :(

I just retrive all information from the registry.
0
 

Author Comment

by:curso
ID: 1201543
I know this, but I prefer ask it by a API to be more indepedent of the localisation of the data in registry.

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Expert Comment

by:MichaelS
ID: 1201544
May be some undocument?
0
 
LVL 86

Expert Comment

by:jkr
ID: 1201545
Fortunately, enumerating shares is common for both NT and 9x here (this is quite unusual for MS ;-) ...

Use 'WNetOpenEnum()' to start the enumeration and 'WNetEnumResource()' to subsequently retrieve the information of all shares of the desired type.

An example can be found at 'http://msdn.microsoft.com/library/sdkdoc/network/networks_77sj.htm', this is what it does:

BOOL WINAPI EnumerateFunc(HWND hwnd,                           HDC hdc,
                          LPNETRESOURCE lpnr){   DWORD dwResult, dwResultEnum;
  HANDLE hEnum;  DWORD cbBuffer = 16384;      // 16K is a good size
  DWORD cEntries = 0xFFFFFFFF; // enumerate all possible entries
  LPNETRESOURCE lpnrLocal;     // pointer to enumerated structures  DWORD i;  
  dwResult = WNetOpenEnum(RESOURCE_GLOBALNET,
                          RESOURCETYPE_ANY,
                          0,        // enumerate all resources
                          lpnr,     // NULL first time this function is called
                          &hEnum);  // handle to resource
  if (dwResult != NO_ERROR)  {  
    // An application-defined error handler is demonstrated in the
    // section titled "Retrieving Network Errors."
    NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetOpenEnum");    return FALSE;  }
  lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer);    do  {  
    ZeroMemory(lpnrLocal, cbBuffer);
    dwResultEnum = WNetEnumResource(hEnum,      // resource handle
                                    &cEntries,  // defined locally as 0xFFFFFFFF
                                    lpnrLocal,  // LPNETRESOURCE
                                    &cbBuffer); // buffer size
    if (dwResultEnum == NO_ERROR)    {      for(i = 0; i < cEntries; i++)      {
        // Following is an application-defined function for
        // displaying contents of NETRESOURCE structures.
        DisplayStruct(hdc, &lpnrLocal[i]);
        // If this NETRESOURCE is a container, call the function
        // recursively.
        if(RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage
                                       & RESOURCEUSAGE_CONTAINER))
          if(!EnumerateFunc(hwnd, hdc, &lpnrLocal[i]))
            TextOut(hdc, 10, 10, "EnumerateFunc returned FALSE.", 29);      }
    }    else if (dwResultEnum != ERROR_NO_MORE_ITEMS)    {
      NetErrorHandler(hwnd, dwResultEnum, (LPSTR)"WNetEnumResource");
      break;    }  }  while(dwResultEnum != ERROR_NO_MORE_ITEMS);
  GlobalFree((HGLOBAL)lpnrLocal);  dwResult = WNetCloseEnum(hEnum);  
  if(dwResult != NO_ERROR)  {
    NetErrorHandler(hwnd, dwResult, (LPSTR)"WNetCloseEnum");    return FALSE;  }
  return TRUE;}

The NETRESOURCE struct filled in by this API holds information on both the UNC name and the local name, so you should be easily able to do the conversion by yourself (by truncating the share name and prepending the local name)

Feel free to ask if you need more information!
0
 

Author Comment

by:curso
ID: 1201546
I succeed to have the shares of the local machine passing NetRessouce struct as parameter of the function EnumerateFunc(..)
NetRessource NETRESOURCE;
NetRessource.lpRemoteName= _T("\\\\mandrill");
NetRessource.dwUsage = RESOURCEUSAGE_CONNECTABLE;

But I do notgot the local path that are shared (the string lpLocalName is empty).
Do I set a other value in the NETRESOURCE struct ?

Thanks in advance.


0
 
LVL 86

Expert Comment

by:jkr
ID: 1201547
From the NETRESOURCE docs:

"lpLocalName

Points to the name of a local device if the dwScope member is RESOURCE_CONNECTED or RESOURCE_REMEMBERED. This member is NULL if the connection does not use a device. Otherwise, it is undefined."

Did you specify this scope?
0
 

Author Comment

by:curso
ID: 1201548
Sorry, but I probably not understood as I should but the lpLocalName is always empty.

Here is the code I use to test the function you sent me.

        NETRESOURCE toto;
      ZeroMemory(&toto, sizeof (NETRESOURCE));
      toto.lpRemoteName= _T("\\\\mandrill");
      toto.dwUsage = RESOURCEUSAGE_CONNECTABLE;
      toto.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
      toto.dwScope  = RESOURCE_REMEMBERED ;
      EnumerateFunc(&toto);

What 's wrong ?
My purpose is :
I have a share (on my machine called MANDRILL) called "projects" (local path: c:\projects), connectable trough "\\MANDRILL\projects".
What I want is  I call a method with in parameter the UNC path: "\\MANDRILL\projects" and it sent back the local path "c:\projects".
The local path is not a mapped drive is really local.

Thanks,
Cataldo.
0
 
LVL 86

Expert Comment

by:jkr
ID: 1201549
>>What I want is  I call a method with in parameter the UNC
>>path: "\\MANDRILL\projects" and it sent back the local
>>path "c:\projects".

Hmm, the direct way to do this is 'NetShareGetInfo()' (though 'WnetEnumResource()' _should_ work - which OS are you using?). The problem with the 'Net*()' functions is that they're implemented differently on NT and 9x, e.g.

// Win9x

char* GetShareLocalName ( char* pszShareName)
{
 static struct share_info_50 si50;

 USHORT us;

 ZeroMemory ( &si50, sizeof ( struct share_info_50);
 lstrcpy ( si50.shi50_netname, pszShareName);

 if ( NERR_Success == NetShareGetInfo ( NULL, pszShareName, 50, (char*) &si50, &us))
      return ( si50.shi50_path);

return ( NULL);
}

// NT (UNICODE only!)

wchar_* GetShareLocalName ( wchar_* pwszShareName)
{
 static SHARE_INFO_2 si2;

 ZeroMemory ( &si2, sizeof ( SHARE_INFO_2));

 if ( NERR_Success == NetShareGetInfo ( NULL, pwszShareName, 2, &si2))
      return ( si2.shi2_path);

 return ( NULL);
}

BTW: There's also 'WNetGetConnection()', but it retrieves the network name for a local device...
0
 
LVL 86

Expert Comment

by:jkr
ID: 1201550
>>wchar_* GetShareLocalName ( wchar_*
>>pwszShareName)

Ooops, this should of course read
wchar_t* GetShareLocalName ( wchar_t* pwszShareName)

Sorry ;-)


0
 

Author Comment

by:curso
ID: 1201551
Hello JKR,

Me again.
I just tried your last solution.
The NetShareGetInfo method returned well NERR_Success
but the struture was completly empty behalf the shi2_netname that contained 2 char (?  and and nonasci char a thin rectangle)


PS:I'm using VC++ 5.0 with its SP3

What's wrong now, is NetShareGetInfo bugged ???

Cataldo.
0
 
LVL 86

Expert Comment

by:jkr
ID: 1201552
>>but the struture was completly empty behalf the
>>shi2_netname that contained 2 char (?  and and nonasci
>>char a thin rectangle)

Hmm, that's strange - you're obviously using NT, are you aware about the UNICODE format?
0
 

Author Comment

by:curso
ID: 1201553
Re Jkr,

I known the shi2_netname is a pointer to a unicode string ,I defined the UNICODE define in the project and in my debuger I set the option show unicode string then the debugger ,normaly has to show me the string correctly.

Cataldo.

Ps: I thank you for your patience.


0
 
LVL 86

Expert Comment

by:jkr
ID: 1201554
Err - why did you reject my answer, then?
0
 

Author Comment

by:curso
ID: 1201555
Sorry,

I did a mistake.

Cataldo.
0
 
LVL 86

Expert Comment

by:jkr
ID: 1201556
So you think I should re-submit this as an answer?
0
 

Author Comment

by:curso
ID: 1201557
I think
0
 

Author Comment

by:curso
ID: 1201558
I think
0
 

Author Comment

by:curso
ID: 1201559
I think
0
 

Author Comment

by:curso
ID: 1201560
I think
0
 

Author Comment

by:curso
ID: 1201561
I think
0
 
LVL 86

Accepted Solution

by:
jkr earned 400 total points
ID: 1201562
Thanx!
0
 

Author Comment

by:curso
ID: 1201563
I think
0
 

Author Comment

by:curso
ID: 1201564
Hello jkr,
wchar_t* UC_Network::GetShareLocalName(wchar_t * pwszShareName)
{
      static SHARE_INFO_2 si2;

      ZeroMemory ( &si2, sizeof ( SHARE_INFO_2));

      if ( ERROR_SUCCESS == NetShareGetInfo ( NULL, pwszShareName, 2, (LPBYTE*) &si2))
      {
            return ( si2.shi2_path);
      }

      return ( NULL);

}

This is the piece of code that have to return the local path of a share on the local machine you sent me.
I compiled this code with the UNICODE define in the project, as si2.shi2_path is a pointer on a unicode string is possible to see it value in the debugger (with the show unicode string set) but I did not see the correcponding local path but a string of 2 char with the first equal to "?" (the GetShareInfo returned NERR_Success).

Do you have any idea what I did wrong


PS:I'm using VC++ 5.0 with its SP3 under NT 4(SP5)





0
 
LVL 86

Expert Comment

by:jkr
ID: 1201565
Ooops, sorry - my fault :-(

Try

#define UNICODE
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <lmcons.h>
#include <lmerr.h>
#include <lmshare.h>
#include <lmaccess.h>
#include <lmapibuf.h>


#ifdef __cplusplus
extern "C"
{
#endif

int __cdecl         wmain                   (   int             argc,  
                                                wchar_t**       argv
                                            );

#ifdef __cplusplus
}
#endif

BOOL GetShareLocalName ( wchar_t* pwszShareName, wchar_t* pwszLocalName, DWORD dwSize)
{
SHARE_INFO_2* psi2  =   NULL;
NET_API_STATUS nas;

    if ( NERR_Success == ( nas = NetShareGetInfo ( NULL, pwszShareName, 2, (UCHAR**) &psi2)) )
{
    lstrcpyn ( psi2->shi2_path, pwszLocalName, dwSize);

    NetApiBufferFree ( psi2);

    return ( TRUE);
}

printf ( "\nERROR: %d\n", nas);

return ( FALSE);
}


int wmain   (   int         argc,  
                wchar_t**   argv
            )
{
    wchar_t awcLocal    [   MAX_PATH] = L"\0";

    if ( 2 != argc) return ( -1);

    GetShareLocalName   (    argv [ 1] , awcLocal, MAX_PATH);

    wprintf ( L"\nNetName %s LocalName: %s\n", argv [ 1], awcLocal);


 return ( 0);
}
0
 

Author Comment

by:curso
ID: 1201566
Hello Jkr,

after replacing "lstrcpyn ( psi2->shi2_path, pwszLocalName, dwSize); " by "wright: lstrcpyn (pwszLocalName,psi2->shi2_path, dwSize);" , It works fine.

Many thanks.
Thank you for your support and patience.


0
 
LVL 86

Expert Comment

by:jkr
ID: 1201567
Ouch ;-)

Should compile&test it before - sorry again...

BTW: Regarding the time of your postings, you seem to be european, also?
0
 

Author Comment

by:curso
ID: 1201568
Yes from Belgium (Brussels)
0
 
LVL 86

Expert Comment

by:jkr
ID: 1201569
Best greetings from the south of germany, then!
0
 

Expert Comment

by:vinny2
ID: 2136050
From NetShareGetInfo help

Only members of the Administrators or Account Operators local group or those with Communication, Print, or Server operator group membership can successfully execute the NetShareGetInfo function at level 2. No special group membership is required for level 0 or level 1 calls.

Cannot use NetShareGetInfo if dont have admin rights, any other ideas out there ??
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

C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

719 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