Visual Basic Network Services
How to Share a Folder using NetShareAdd
     
Posted:   Monday January 21, 2002
Updated:   Monday December 26, 2011
     
Applies to:   VB4-32, VB5, VB6
Developed with:   VB6, Windows XP
OS restrictions:   None, but see comments
Author:   VBnet - Randy Birch
     

Related:  

WNetAddConnection2: Transparently Connect to Network Shares
NetShareCheck: Determine Remote Folder or Device Share Status
WNetEnumResource: Enumerating Local Network Resources
NetConnectionEnum: Enumerating Share Connection Information
NetShareEnum: Enumerating Shared Resources on Other Machines  
NetShareAdd: Create a Local or Remote Share
WNetGetUser: User, Share and Share User for Network Resources
WNetGetConnection: Get UNC Path for Mapped Drive

     
 Prerequisites
See comments following the code.

The NetShareAdd function shares a server or workstation resource. Only members of the Administrators or Account Operators local group, or those with Communication, Print, or Server operator group membership can successfully execute the NetShareAdd function. The Print operator can add only Printer queues. The Communication operator can add only communication-device queues.

Although NetShareAdd can be called by all 32-bit Windows versions, the code in the demo is only for NT / 2000 / XP. See the Comments below for 9x methodology.

In the NT code, the server name parameter is a pointer to a string specifying the name of the remote server on which the function is to execute. The string must begin with \\. If this parameter is null the local computer is used. On NT / 2000 / XP the call can pass either a SHARE_INFO_2 or SHARE_INFO_502 structure. Win9x machines must pass a SHARE_INFO_50 type. In addition, on 9x the string specified in the shi50_path member can only be upper case. This restriction does not apply to any string under NT+.

 BAS Module Code
None.

 Form Code
To a form add a command button (Command1) and five text boxes (Text1 - Text5). Labels are optional. Add the following to the form:

Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved.
' Some pages may also contain other copyrights by the author.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Distribution: You can freely use this code in your own
'               applications, but you may not reproduce 
'               or publish this code on any web site,
'               online service, or distribute as source 
'               on any media without express permission.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Const NERR_SUCCESS As Long = 0&

'share types
Private Const STYPE_ALL As Long = -1  'note: my const
Private Const STYPE_DISKTREE As Long = 0
Private Const STYPE_PRINTQ As Long = 1
Private Const STYPE_DEVICE As Long = 2
Private Const STYPE_IPC As Long = 3
Private Const STYPE_SPECIAL As Long = &H80000000

'permissions
Private Const ACCESS_READ As Long = &H1
Private Const ACCESS_WRITE As Long = &H2
Private Const ACCESS_CREATE As Long = &H4
Private Const ACCESS_EXEC As Long = &H8
Private Const ACCESS_DELETE As Long = &H10
Private Const ACCESS_ATRIB As Long = &H20
Private Const ACCESS_PERM As Long = &H40
Private Const ACCESS_ALL As Long = ACCESS_READ Or _
                                   ACCESS_WRITE Or _
                                   ACCESS_CREATE Or _
                                   ACCESS_EXEC Or _
                                   ACCESS_DELETE Or _
                                   ACCESS_ATRIB Or _
                                   ACCESS_PERM

Private Type SHARE_INFO_2
  shi2_netname As Long
  shi2_type As Long
  shi2_remark As Long
  shi2_permissions As Long
  shi2_max_uses As Long
  shi2_current_uses  As Long
  shi2_path As Long
  shi2_passwd As Long
End Type
  
Private Declare Function NetShareAdd Lib "netapi32" _
  (ByVal servername As Long, _
   ByVal level As Long, _
   buf As Any, _
   parmerr As Long) As Long

   

Private Sub Form_Load()
  
   Text1.Text = "\\" & Environ$("COMPUTERNAME")
   Text2.Text = "c:\program files\adobe"
   Text3.Text = "vbnetdemo"
   Text4.Text = "VBnet demo test share"
   Text5.Text = ""
   
End Sub


Private Sub Command1_Click()

   Dim success As Long
               
   success = ShareAdd(Text1.Text, _
                      Text2.Text, _
                      Text3.Text, _
                      Text4.Text, _
                      Text5.Text)
                      
   Select Case success
      Case 0:    MsgBox "share created successfully!"
      Case 2118: MsgBox "share name already exists"
      Case Else: MsgBox "create error " & success
   End Select

End Sub


Private Function ShareAdd(sServer As String, _
                          sSharePath As String, _
                          sShareName As String, _
                          sShareRemark As String, _
                          sSharePw As String) As Long
   
   Dim dwServer   As Long
   Dim dwNetname  As Long
   Dim dwPath     As Long
   Dim dwRemark   As Long
   Dim dwPw       As Long
   Dim parmerr    As Long
   Dim si2        As SHARE_INFO_2
   
  'obtain pointers to the server, share and path
   dwServer = StrPtr(sServer)
   dwNetname = StrPtr(sShareName)
   dwPath = StrPtr(sSharePath)
   
  'if the remark or password specified,
  'obtain pointer to those as well
   If Len(sShareRemark) > 0 Then
      dwRemark = StrPtr(sShareRemark)
   End If
   
   If Len(sSharePw) > 0 Then
      dwPw = StrPtr(sSharePw)
   End If
      
  'prepare the SHARE_INFO_2 structure
   With si2
      .shi2_netname = dwNetname
      .shi2_path = dwPath
      .shi2_remark = dwRemark
      .shi2_type = STYPE_DISKTREE
      .shi2_permissions = ACCESS_ALL
      .shi2_max_uses = -1
      .shi2_passwd = dwPw
   End With
                          
  'add the share
   ShareAdd = NetShareAdd(dwServer, _
                          2, _
                          si2, _
                          parmerr)
                          
End Function
 Comments

NetShareAdd for Win9x uses the share_info_50 structure shown below. Following the structure definition is the MSDN demo C code from showing how this API is used on 9x machines. Since I do not have a 9x box, I am unable to translate and test the code, but the NT code above should provide sufficient example to get going.
C Declare for share_info_50
struct _share_info_50 {
  char            shi50_netname[LM20_NNLEN+1];
  unsigned char   shi50_type;
  unsigned short  shi50_flags;
  char FAR *      shi50_remark;
  char FAR *      shi50_path;
  char            shi50_rw_password[SHPWLEN+1];
  char            shi50_ro_password[SHPWLEN+1];
};

VB Declare for share_info_50. Note that strings above 
are declared As Long, indicating a pointer to the 
string needs to be passed.
'for use on Win9x only
Private Type SHARE_INFO_50
  shi50_netname As Long
  shi50_type As Long
  shi50_flags  As Long
  shi50_remark As Long
  shi50_path As Long
  shi50_rw_password As Long
  shi50_ro_password As Long
End Type

Alternatively, you could try using a byte array for 
the char array members:
Private Type SHARE_INFO_50
  shi50_netname (0 to LM20_NNLEN) As Byte
  shi50_type As Long
  shi50_flags  As Long
  shi50_remark As Long
  shi50_path As Long
  shi50_rw_password (0 to SHPWLEN) As Byte
  shi50_ro_password (0 to SHPWLEN) As Byte
  pad1 As Long
End Type

Note that in 9x/ME, NetShareAdd is 
declared in the library Svrapi, rather 
than NT's Netapi32.

Sample C code for Win9x

int main(int argc, char FAR * argv[])
{
   char FAR * pszServerName = NULL;
   short nLevel = 50;
   struct share_info_50* pBuf = NULL;
   unsigned short cbBuffer;
   NET_API_STATUS nStatus;
   //
   // ServerName can be NULL to indicate the local computer.
   //
   if ((argc < 3) || (argc > 4))
   {
      printf("Usage: %s [\\\\ServerName] ShareName SharePath\n", argv[0]);
      exit(1);
   }

   if (argc == 4)
      pszServerName = argv[1];
   //
   // Allocate the memory required to specify a 
   //   share_info_50 structure.
   //
   cbBuffer = sizeof(struct share_info_50);
   pBuf = malloc(cbBuffer);

   if (pBuf == NULL)
      printf("No memory\n");
   //
   // Assign values to the share_info_50 structure.
   //
   strcpy(pBuf->shi50_netname, argv[argc-2]);
   pBuf->shi50_type = STYPE_DISKTREE;
   pBuf->shi50_flags = SHI50F_FULL;
   pBuf->shi50_remark = NULL;
   pBuf->shi50_path = argv[argc-1];
   pBuf->shi50_rw_password[0] = '\0'; // No password
   pBuf->shi50_ro_password[0] = '\0'; // No password
   //
   // Call the NetShareAdd function
   //  specifying information level 50.
   //
   nStatus = NetShareAdd(pszServerName,
                         nLevel,
                         (char FAR *)pBuf,
                         cbBuffer);
   //
   // Display the result of the function call.
   //
   if (nStatus == NERR_Success)
      printf("Share added successfully\n");
   else
      fprintf(stderr, "A system error has occurred: %d\n", nStatus);
   //
   // Free the allocated memory.
   //
   if (pBuf != NULL)
      free(pBuf);

   return 0;
}

 
 

PayPal Link
Make payments with PayPal - it's fast, free and secure!

 
 
 
 

Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved.
Terms of Use  |  Your Privacy

 

Hit Counter