• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 479
  • Last Modified:

Local shares and converting UNC to local path

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
curso
Asked:
curso
  • 16
  • 11
  • 2
  • +1
1 Solution
 
cursoAuthor Commented:
Edited text of question.
0
 
MichaelSCommented:
It's no problem in the NT, but 9x :(

I just retrive all information from the registry.
0
 
cursoAuthor Commented:
I know this, but I prefer ask it by a API to be more indepedent of the localisation of the data in registry.

0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
MichaelSCommented:
May be some undocument?
0
 
jkrCommented:
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
 
cursoAuthor Commented:
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
 
jkrCommented:
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
 
cursoAuthor Commented:
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
 
jkrCommented:
>>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
 
jkrCommented:
>>wchar_* GetShareLocalName ( wchar_*
>>pwszShareName)

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

Sorry ;-)


0
 
cursoAuthor Commented:
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
 
jkrCommented:
>>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
 
cursoAuthor Commented:
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
 
jkrCommented:
Err - why did you reject my answer, then?
0
 
cursoAuthor Commented:
Sorry,

I did a mistake.

Cataldo.
0
 
jkrCommented:
So you think I should re-submit this as an answer?
0
 
cursoAuthor Commented:
I think
0
 
cursoAuthor Commented:
I think
0
 
cursoAuthor Commented:
I think
0
 
cursoAuthor Commented:
I think
0
 
cursoAuthor Commented:
I think
0
 
jkrCommented:
Thanx!
0
 
cursoAuthor Commented:
I think
0
 
cursoAuthor Commented:
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
 
jkrCommented:
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
 
cursoAuthor Commented:
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
 
jkrCommented:
Ouch ;-)

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

BTW: Regarding the time of your postings, you seem to be european, also?
0
 
cursoAuthor Commented:
Yes from Belgium (Brussels)
0
 
jkrCommented:
Best greetings from the south of germany, then!
0
 
vinny2Commented:
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

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

  • 16
  • 11
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now