|< Windows Share Programming 1 | Main | Windows Process & Threads: C Run-Time 1 >| Site Index | Download |


 

 

 

 

MODULE Q1

WINDOWS OS

.:: SHARE:  STORY AND PROGRAM EXAMPLES::.

PART 2

 

 

 

 

What do we have in this Module?

  1. Network Management Functions

  2. NetShareCheck()

  3. Parameters

  4. Program Example

  5. NetShareEnum()

  6. Parameters

  7. Remarks

  8. Program Example

  9. NetShareDel()

  10. Program Example

My Training Period: xx hours. Before you begin, read some instruction here.

 

 

 

 

 

 

 

 

 

 

 

 

The expected skills:

Network Management Functions

 

NetShareCheck()

 

Item

Description

Function

NetShareCheck().

Use

To check whether or not a server is sharing a device.

Prototype

NET_API_STATUS NetShareCheck( LPWSTR servername, LPWSTR device, LPDWORD type);

Parameters

See below.

Return value

If the function succeeds, the return value is NERR_Success.  If the function fails, the return value can be one of the following error codes.

  1. ERROR_NOT_ENOUGH_MEMORY - Insufficient memory is available.

  2. NERR_DeviceNotShared - The device is not shared.

Include file

<lm.h>

Remark

No special group membership is required to successfully execute the NetShareCheck() function.  If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to achieve the same functionality you can achieve by calling the network management share functions.

 

Table 14.

 

Parameters

 

servername - [in] Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is NULL, the local computer is used.  For Windows NT, this string must begin with \\.

device - [in] Pointer to a string that specifies the name of the device to check for shared access.

type - [out] Pointer to a DWORD that receives the type of the shared device.  This parameter is set only if the function returns successfully.  This parameter can be one of the following values.

 

Value

Meaning

STYPE_DISKTREE

Disk drive.

STYPE_PRINTQ

Print queue.

STYPE_DEVICE

Communication device.

STYPE_IPC

Interprocess communication (IPC).

STYPE_SPECIAL

Special share reserved for interprocess communication (IPC$) or remote administration of the server (ADMIN$).  Can also refer to administrative shares such as C$, D$, E$, and so forth.

STYPE_TEMPORARY

A temporary share.

 

Table 15.

 

A Program Example

 

The following code sample demonstrates how to check whether a server is sharing a device, using a call to the NetShareCheck() function.  The function returns the type of device being shared, as described in the preceding documentation for the type parameter.

 

// add the netapi32.lib...

// The return value of share functions code can be found in

// Network Management Error Codes in MSDN

// For Win Xp Pro, adjust accordingly for other Windows version

#define _WIN32_WINNT 0x0501

#define UNICODE

#include <windows.h>

#include <stdio.h>

#include <lm.h>

 

int wmain(int argc, TCHAR *argv[])

{

   NET_API_STATUS res;

   DWORD devType = 0;

   if(argc < 3)

      printf("Usage: %ls <server_name> <device_name>\n", argv[0]);

   else

   {

      // Call the NetShareCheck() function.

      res = NetShareCheck(argv[1], _wcsupr(argv[2]), &devType);

      // If the function succeeds, inform the user.

      if(res == 0)

         switch(devType)

         {

                case 0 : printf("Device is shared as type STYPE_DISKTREE - disk drive/folder.");

                       break;

                case 1 : printf("Device is shared as type STYPE_PRINTQ - Print queue.");

                       break;

                case 2 : printf("Device is shared as type STYPE_DEVICE - Communication device.");

                       break;

                case 3 : printf("Device is shared as type STYPE_IPC - Interprocess communication (IPC).");

                       break;

                case 4 : printf("Device is shared as type STYPE_SPECIAL - Special share reserved \

                                     for interprocess communication (IPC$) or \

                                     remote administration of the server (ADMIN$). \

                                     Can also refer to administrative shares such as C$, D$, E$, and so forth.");

                       break;

                case 5 : printf("Device is shared as type STYPE_TEMPORARY - A temporary share.");

                       break;

         }

      // Otherwise, print the return error code.

      else

         printf("Something wrong, error: %u\n", res);

   }

   return 0;

}

 

A sample output:

F:\myproject\win32prog\Debug>sharecheck

Usage: sharecheck <server_name> <device_name>

F:\myproject\win32prog\Debug>sharecheck mypersonal F:\\mypersonal

Device is shared as type STYPE_DISKTREE - disk drive/folder.

F:\myproject\win32prog\Debug>sharecheck mypersonal IPC

Device is shared as type STYPE_DISKTREE - disk drive/folder.

F:\myproject\win32prog\Debug>sharecheck mypersonal C$

Device is shared as type STYPE_DISKTREE - disk drive/folder.

F:\myproject\win32prog\Debug>sharecheck mypersonal C

Device is shared as type STYPE_DISKTREE - disk drive/folder.

F:\myproject\win32prog\Debug>sharecheck mypersonal D

Device is shared as type STYPE_DISKTREE - disk drive/folder.

 

F:\myproject\win32prog\Debug>

 

The NetShareEnum()

 

Item

Description

Function

NetShareEnum().

Use

To retrieve information about each shared resource on a server.  You can also use the WNetEnumResource() function to retrieve resource information. However, WNetEnumResource() does not enumerate hidden shares or users connected to a share.

Prototype

NET_API_STATUS NetShareEnum( LPWSTR servername, DWORD level, LPBYTE* bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries, LPDWORD resume_handle);

Parameters

See below.

Return value

If the function succeeds, the return value is NERR_Success.  If the function fails, the return value is a system error code.  Error codes are System Error Codes.

Include file

<lm.h>

Remark

See below.

 

Table 16.

 

Parameters

 

servername - [in] Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute. If this parameter is NULL, the local computer is used.  For Windows NT, this string must begin with \\.

level - [in] Specifies the information level of the data.  This parameter can be one of the following values.

 

Value

Meaning

0

Return share names.  The bufptr parameter points to an array of SHARE_INFO_0 structures.

1

Return information about shared resources, including the name and type of the resource, and a comment associated with the resource.  The bufptr parameter points to an array of SHARE_INFO_1 structures.

2

Return information about shared resources, including name of the resource, type and permissions, password, and number of connections.  The bufptr parameter points to an array of SHARE_INFO_2 structures.

50

Windows Me/98/95:  Return information about shared resources, including the name and type of the resource, a comment associated with the resource, and passwords.  The pbBuffer parameter points to an array of share_info_50 structures.

502

Return information about shared resources, including name of the resource, type and permissions, number of connections, and other pertinent information.  The bufptr parameter points to an array of SHARE_INFO_502 structures.

 

Table 17.

 

bufptr - [out] Pointer to the buffer that receives the data.  The format of this data depends on the value of the level parameter.

This buffer is allocated by the system and must be freed using the NetApiBufferFree() function.  Note that you must free the buffer even if the function fails with ERROR_MORE_DATA.

prefmaxlen - [in] Specifies the preferred maximum length of returned data, in bytes.  If you specify MAX_PREFERRED_LENGTH, the function allocates the amount of memory required for the data.  If you specify another value in this parameter, it can restrict the number of bytes that the function returns.  If the buffer size is insufficient to hold all entries, the function returns ERROR_MORE_DATA.

entriesread - [out] Pointer to a value that receives the count of elements actually enumerated.

totalentries - [out] Pointer to a value that receives the total number of entries that could have been enumerated.  Note that applications should consider this value only as a hint.

resume_handle - [in, out] Pointer to a value that contains a resume handle which is used to continue an existing share search.  The handle should be zero on the first call and left unchanged for subsequent calls.  If resume_handle is NULL, then no resume handle is stored.

 

Some Notes

 

Administrator, Power User, Print Operator, or Server Operator group membership is required to successfully execute the NetShareEnum() function at levels 2 and 502.  No special group membership is required for level 0 or level 1 call.  To retrieve a value that indicates whether a share is the root volume in a Dfs tree structure, you must call the NetShareGetInfo() function and specify information level 1005.  If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to achieve the same functionality you can achieve by calling the network management share functions. 

Windows Server 2003 and Windows XP:  If you call this function at information level 2 or 502 on a domain controller that is running Active Directory, access is allowed or denied based on the ACL for the securable object.  To enable anonymous access, the user Anonymous must be a member of the "Pre-Windows 2000 compatible access" group.  This is because anonymous tokens do not include the Everyone group SID by default.  If you call this function at information level 2 or 502 on a member server or workstation, all authenticated users can view the information.  Anonymous access is also permitted if the EveryoneIncludesAnonymous policy setting allows anonymous access.

For Windows 2000:  If you call this function at information level 2 or 502 on a domain controller that is running Active Directory, access is allowed or denied based on the access control list (ACL) for the securable object.  The default ACL permits all authenticated users and members of the "Pre-Windows 2000 compatible access" group to view the information.  By default, the "Pre-Windows 2000 compatible access" group includes Everyone as a member.  This enables anonymous access to the information if the system allows anonymous access.  If you call this function at information level 2 or 502 on a member server or workstation, all authenticated users can view the information.  Anonymous access is also permitted if the RestrictAnonymous policy setting allows anonymous access.

 

A Program Example

 

The following code sample demonstrates how to retrieve information about each shared resource on a server using a call to the NetShareEnum() function.  The sample calls NetShareEnum(), specifying information level 502 ( SHARE_INFO_502).  If the call succeeds, the code loops through the entries and prints information about each share. The sample also calls the IsValidSecurityDescriptor() function to validate the shi502_security_descriptor member.  Finally, the code sample frees the memory allocated for the information buffer by calling NetApiBufferFree().

 

// add the netapi32.lib...

// The return value of share functions code can be found in

// Network Management Error Codes in MSDN

// For Win Xp Pro, adjust accordingly for other Windows version

#define _WIN32_WINNT 0x0501

#define UNICODE

#include <windows.h>

#include <stdio.h>

#include <lm.h>

 

int wmain(int argc, TCHAR *lpszArgv[ ])

{

   PSHARE_INFO_502 BufPtr, pth;

   NET_API_STATUS  res;

   LPTSTR          lpszServer = NULL;

   DWORD er = 0, tr = 0, resume = 0, I;

   if(argc != 2)

   {

          printf("Usage: %ls <server_name>\n", lpszArgv[0]);

          exit (1);

   }

else

     lpszServer = lpszArgv[1];

   // Print a report header.

   printf("\nShare        Local Path                 Uses     Sec. Descriptor\n");

   printf("----------------------------------------------------------------\n");

   // Call the NetShareEnum() function; specify level 502.

   do // begin do

   {

      res = NetShareEnum(lpszServer, 502, (LPBYTE *)&BufPtr, -1, &er, &tr, &resume);

      // If the call succeeds,

      if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA)

      {

         pth = BufPtr;

         // Loop through the entries, print the retrieved data.

         for(i=1; i<=er; i++)

         {

            printf("%-16S%-26S%-8u",pth->shi502_netname, pth->shi502_path, pth->shi502_current_uses);

            // Validate the value of the shi502_security_descriptor member.

            if (IsValidSecurityDescriptor(pth->shi502_security_descriptor))

               printf("Yes\n");

            else

               printf("No\n");

            pth++;

         }

         // Free the allocated buffer.

         NetApiBufferFree(BufPtr);

      }

      else

         printf("Something wrong, error: %ld\n", res);

   }

   // Continue to call NetShareEnum() while there are more entries.

   while (res == ERROR_MORE_DATA); // end do

   return 0;

}

 

A sample output:

F:\myproject\win32prog\Debug>enumshare

Usage: enumshare <server_name>

 

F:\myproject\win32prog\Debug>enumshare mypersonal

 

Share        Local Path                 Uses     Sec. Descriptor

----------------------------------------------------------------

E$                E:\                       0       No

mytestshare     F:\myfolder               0       No

IPC$                                       0       No

D$              D:\                       0       No

I$                  I:\                       0       No

G$             G:\                       0       No

F$              F:\                       0       No

ADMIN$          C:\WINDOWS                0       No

H$             H:\                       0       No

wwwroot$        c:\inetpub\wwwroot        0       Yes

C$            C:\                       0       No

 

F:\myproject\win32prog\Debug>

 

NetShareDel()

 

Item

Description

Function

NetShareDel().

Use

To delete a share name from a server’s list of shared resources, disconnecting all connections to the shared resource.

Prototype

NET_API_STATUS NetShareDel( LMSTR servername, LMSTR netname, DWORD reserved);

Parameters

servername - [in] Pointer to a string that specifies the DNS or NetBIOS name of the remote server on which the function is to execute.  If this parameter is NULL, the local computer is used.  For Windows NT, this string must begin with \\.  This string is Unicode if _WIN32_WINNT or FORCE_UNICODE are defined.

netname - [in] Pointer to a string that specifies the name of the share to delete.  This string is Unicode if _WIN32_WINNT or FORCE_UNICODE are defined.

reserved - Reserved, must be zero.

Return value

If the function succeeds, the return value is NERR_Success.  If the function fails, the return value can be one of the following error codes:

  1. ERROR_ACCESS_DENIED – The user does not have access to the requested information.

  2. ERROR_INVALID_PARAMETER – The specified parameter is invalid.

  3. ERROR_NOT_ENOUGH_MEMORY – Insufficient memory is available.

  4. NERR_NetNameNotFound – The share name does not exist.

Include file

<lm.h>

Remark

Only members of the Administrators, Server Operators, or Power Users local group, or those with Server Operator group membership, can successfully delete file shares with a call to the NetShareDel() function.  The Print Operator can delete printer shares.

If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to achieve the same functionality you can achieve by calling the network management share functions.

 

Table 18.

 

A Program Example

 

The following code sample demonstrates how to delete a share created in our previous program example using the NetShareDel() function.

 

// add the netapi32.lib...

// The return value of share functions code can be found in

// Network Management Error Codes in MSDN

// For Win Xp Pro, adjust accordingly for other Windows version

#define _WIN32_WINNT 0x0501

#define UNICODE

#include <windows.h>

#include <stdio.h>

#include <lm.h>

 

int wmain(int argc, TCHAR *argv[ ])

{

   NET_API_STATUS res;

   if(argc != 3)

      printf("Usage: %ls <server_name> <share_name>\n", argv[0]);

   else

   {

      // Call the NetShareDel() function to delete the share.

      res = NetShareDel(argv[1], argv[2], 0);

      //Display the result of the call.

      if(res == 0)

         printf("%ls share successfully removed.\n", argv[2]);

      else

         printf("Something wrong, error: %u\n", res);

   }

   return 0;

}

 

A sample output:

F:\myproject\win32prog\Debug>removeshare

Usage: removeshare <server_name> <share_name>

 

F:\myproject\win32prog\Debug>removeshare mypersonal mytestshare

mytestshare share successfully removed.

 

F:\myproject\win32prog\Debug>

The following are some of the previous program examples run in a domain based network.  They were run on Windows 2000 member server jmti_st_00 against its Domain Controller (DC), Mawar (Mawar.jmtibm.com).  Compiler used is Microsoft Visual C++ 6.0.

 

// This example run on member server creating share on the

// domain controller (DC)...

// Don’t forget to add netapi32.lib to your project…

// The return value of share functions code can be found in

// Network Management Error Codes in MSDN…

// For Win 2000 server, adjust accordingly for other Windows version

 

#define _WIN32_WINNT 0x0500

#define UNICODE

#include <windows.h>

#include <stdio.h>

#include <lm.h>

 

// Unicode main()...

int wmain(int argc, TCHAR *argv[ ])

{

   NET_API_STATUS res;

   SHARE_INFO_2 p;

   DWORD parm_err = 0;

   // Some prompt...

   if(argc != 4)

      printf("Usage: %ls <server_name> <share_name> <share_remark>\n", argv[0]);

   else

   {

      // Fill in the SHARE_INFO_2 structure.

      p.shi2_netname = LPWSTR(argv[2]);   

      p.shi2_type = STYPE_DISKTREE;     // disk drive including the directory...

      p.shi2_remark = LPWSTR(argv[3]);  // share remark

      p.shi2_permissions = ACCESS_ALL;  // all permission

      p.shi2_max_uses = -1;             // unlimited

      p.shi2_current_uses = 0;          // no current uses

      // Try finding a way to accept the share path through the command line...

      p.shi2_path = TEXT("E:\\Domainshare"); // share path, here we want to share a folder

      p.shi2_passwd = NULL;       // no password

      // Call the NetShareAdd() function, specifying level 2.

      res = NetShareAdd(argv[1], 2, (LPBYTE) &p, &parm_err);

      // If the call succeeds, inform the user.

      if(res==0)

         printf("%ls share created successfully.\n", p.shi2_netname);

      // Otherwise, print an error, and identify the parameter in error.

      else

          printf("Failed to create %ls, error: %u parmerr = %u\n", p.shi2_netname, res, parm_err);

   }

   return 0;

}

 

A sample output:

C:\myproject\win32prog\Debug>addsharedom

Usage: addsharedom <server_name> <share_name> <share_remark>

 

C:\myproject\win32prog\Debug>addsharedom mawar.jmtibm.com mydomainshare “Domain based share”

mydomainshare share created successfully.

 

C:\myproject\win32prog\Debug>

 

Then let verify our task.

 

// add the netapi32.lib...

// The return value of share functions code can be found in

// Network Management Error Codes in MSDN

// For Win 2000 server, adjust accordingly for other Windows version

#define _WIN32_WINNT 0x0500

#define UNICODE

#include <windows.h>

#include <stdio.h>

#include <lm.h>

 

int wmain(int argc, TCHAR *lpszArgv[ ])

{

   PSHARE_INFO_502 BufPtr, pth;

   NET_API_STATUS  res;

   LPTSTR          lpszServer = NULL;

   DWORD er = 0, tr = 0, resume = 0, i;

   if(argc != 2)

   {

          printf("Usage: %ls <server_name>\n", lpszArgv[0]);

          exit (1);

   }

else

     lpszServer = lpszArgv[1];

   // Print a report...

   printf("\nShare        Local Path                                   Uses     Sec. Descriptor\n");

   printf("------------------------------------------------------------------------------------\n");

   // Call the NetShareEnum() function; specifying level 502.

   do // begin do

   {

      res = NetShareEnum(lpszServer, 502, (LPBYTE *)&BufPtr, -1, &er, &tr, &resume);

      // If the call succeeds...

      if(res == ERROR_SUCCESS || res == ERROR_MORE_DATA)

      {

         pth = BufPtr;

         // Loop through the entries, print the retrieved data.

         for(i=1; i<=er; i++)

         {

            printf("%-16S%-44S%-8u",pth->shi502_netname, pth->shi502_path, pth->shi502_current_uses);

            // Validate the value of the shi502_security_descriptor member.

            if (IsValidSecurityDescriptor(pth->shi502_security_descriptor))

               printf("Yes\n");

            else

               printf("No\n");

            pth++;

         }

         // Free the allocated buffer.

         NetApiBufferFree(BufPtr);

      }

      else

         printf("Something wrong, error: %ld\n", res);

   }

   // Continue to call NetShareEnum() while there are more entries.

   while (res == ERROR_MORE_DATA); // end do

   return 0;

}

 

A sample output:

C:\myproject\win32prog\Debug>enumsharedom

Usage: enumsharedom <server_name>

 

C:\myproject\win32prog\Debug>enumsharedom mawar

 

Share        Local Path                                   Uses     Sec. Descriptor

----------------------------------------------------------------------------------

E$              E:\                                         0       No

IPC$                                                        2       No

Resources$      C:\Program Files\Exchsrvr\res               0       Yes

NETLOGON        C:\WINNT\SYSVOL\sysvol\jmtibm.com\SCRIPTS   0       Yes

MAWAR.log       C:\Program Files\Exchsrvr\MAWAR.log         0       Yes

F$              F:\                                         0       No

ADMIN$          C:\WINNT                                    0       No

SYSVOL          C:\WINNT\SYSVOL\sysvol                      0       Yes

mydomainshare   E:\Domainshare                              0       No

C$              C:\                                         0       No

Address         C:\Program Files\Exchsrvr\address           0       Yes

 

C:\myproject\win32prog\Debug>

 

 

------------End of Module Q-------------

 

 

 

 

 

 

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Check the best selling C, C++ and Windows books at Amazon.com.
  2. Microsoft Visual C++, online MSDN.
  3. MSDN library.
  4. For Multibytes, Unicode characters and Localization please refer to Locale, wide characters & Unicode (Story) and Windows users & groups programming tutorials (Implementation).
  5. Structure, enum, union and typedef story can be found C/C++ struct, enum, union & typedef.
  6. Notation used in MSDN is Hungarian Notation instead of CamelCase and is discussed Windows programming notations.
  7. Windows data type information is in Windows data types used in Win32 programming.

 

 

 

 

 

 

 

|< Windows Share Programming 1 | Main | Windows Process & Threads: C Run-Time 1 >| Site Index | Download |