Code:
// === Structures and Definitions =============================================
struct share_info_50 {
char shi50_netname[ 13 ];
unsigned char shi50_type;
unsigned short shi50_flags;
char FAR * shi50_remark;
char FAR * shi50_path;
char shi50_rw_pssword[ 9 ];
char shi50_ro_password[ 9 ];
};
typedef struct _SHARE_INFO_2 {
LPSTR shi2_netname;
DWORD shi2_type;
LPSTR shi2_remark;
DWORD shi2_permissions;
DWORD shi2_max_uses;
DWORD shi2_current_uses;
LPSTR shi2_path;
LPSTR shi2_passwd;
} SHARE_INFO_2, *PSHARE_INFO_2, *LPSHARE_INFO_2;
#define SHI50F_RDONLY 0x0001
#define SHI50F_FULL 0x0002
#define SHI50F_DEPENDSON (SHI50F_RDONLY|SHI50F_FULL)
#define SHI50F_ACCESSMASK (SHI50F_RDONLY|SHI50F_FULL)
#define SHI50F_PERSIST 0x0100
#define SHI50F_SYSTEM 0x0200
#define STYPE_DISKTREE 0
#define SHI_USES_UNLIMITED (DWORD)-1
#define NET_API_STATUS DWORD
// === This is called by an application =======================================
BOOL ShareDirectory( HWND hParent, LPSTR lpShareName, LPSTR lpPath,
LPSTR lpRemark, LPSTR lpPassword )
{
OSVERSIONINFO osvi;
memset( &osvi, 0, sizeof(OSVERSIONINFO) ); // Initialize version struct
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); // Fill in size
GetVersionEx( &osvi ); // Get OS version info
if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT ) // If it's WinNT...
return( WNTShareDirectory( hParent, lpShareName, lpPath, // do this
lpRemark, lpPassword ) );
else
return( W95ShareDirectory( hParent, lpShareName, lpPath, // If it's '95
lpRemark, lpPassword ) ); // do that
}
// === Windows 95 Share Function ==============================================
BOOL W95ShareDirectory( HWND hParent, LPSTR lpShareName, LPSTR lpPath,
LPSTR lpRemark, LPSTR lpPassword )
{
NET_API_STATUS status;
struct share_info_50 si50;
HANDLE hModule;
NET_API_STATUS ( WINAPI *pNetShareAdd )( LPSTR, USHORT, LPBYTE, USHORT );
strupr( lpPath ); // Path must be uppercase
memset( &si50, 0, sizeof(struct share_info_50) ); // Initialize struct
strcpy( si50.shi50_netname, lpShareName ); // Share name is copied
si50.shi50_type = STYPE_DISKTREE;
si50.shi50_remark = lpRemark; // Remark and path are pointed to
si50.shi50_path = lpPath;
strcpy( si50.shi50_rw_password, lpPassword ); // Passwords are copied
strcpy( si50.shi50_ro_password, lpPassword );
si50.shi50_flags = SHI50F_PERSIST | SHI50F_FULL;
hModule = LoadLibrary( "SVRAPI.DLL" ); // This is NETAPI32.DLL in WinNT
status = 1; // Error if module not loaded
if( hModule )
{ // If DLL loaded, look for sharing function
(DWORD)pNetShareAdd = (DWORD)GetProcAddress( hModule, "NetShareAdd" );
if( pNetShareAdd ) // And if that's found, call it
status = pNetShareAdd( NULL, 50, (LPBYTE)&si50,
sizeof(struct share_info_50) );
FreeLibrary( hModule ); // Free library if it loaded
}
if( ! status ) // Zero is good...return TRUE on no error
return( TRUE );
return( FALSE ); // Error brings FALSE return
}
// === Windows NT Share Function ==============================================
BOOL WNTShareDirectory( HWND hParent, LPSTR lpShareName, LPSTR lpPath,
LPSTR lpRemark, LPSTR lpPassword )
{
NET_API_STATUS status;
SHARE_INFO_2 si2;
HANDLE hModule;
NET_API_STATUS ( WINAPI *pNetShareAdd )( LPSTR, DWORD, LPBYTE, LPDWORD );
DWORD dwErr;
BYTE *bUnicodePath, *bUnicodeShare, *bUnicodeRemark, *bUnicodePassword;
strupr( lpPath ); // Make path upper case
bUnicodePath = GlobalAllocPtr( GHND, // Allocate space for Unicode path
( strlen( lpPath ) * 2 ) + 2 );
if( ! bUnicodePath )
return( FALSE );
bUnicodeShare = GlobalAllocPtr( GHND, // Allocate space for Unicode name
( strlen( lpShareName ) * 2 ) + 2 );
if( ! bUnicodeShare )
{
GlobalFreePtr( bUnicodePath );
return( FALSE );
}
// Convert one byte strings into Unicode strings
MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
lpPath, strlen( lpPath ),
bUnicodePath, ( strlen( lpPath ) * 2 ) + 2 );
MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
lpShareName, strlen( lpShareName ),
bUnicodeShare, ( strlen( lpShareName ) * 2 ) + 2 );
if( strlen( lpPassword ) ) // If the password is not zero length
{ // Convert it to Unicode
bUnicodePassword = GlobalAllocPtr( GHND,
( strlen( lpPassword ) * 2 ) + 2 );
if( bUnicodePassword )
MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
lpPassword, strlen( lpPassword ),
bUnicodePassword,
( strlen( lpPassword ) * 2 ) + 2 );
else
bUnicodePassword = NULL;
}
else
bUnicodePassword = NULL;
if( strlen( lpRemark ) ) // And if the remark is not zero length
{ // convert it to Unicode, too
bUnicodeRemark = GlobalAllocPtr( GHND,
( strlen( lpRemark ) * 2 ) + 2 );
if( bUnicodeRemark )
MultiByteToWideChar( CP_ACP, MB_ERR_INVALID_CHARS,
lpRemark, strlen( lpRemark ),
bUnicodeRemark,
( strlen( lpRemark ) * 2 ) + 2 );
else
bUnicodeRemark = NULL;
}
else
bUnicodeRemark = NULL; // If either is zero length, pointer is NULL
memset( &si2, 0, sizeof(SHARE_INFO_2) );
si2.shi2_netname = bUnicodeShare; // Point to name and path
si2.shi2_path = bUnicodePath;
si2.shi2_type = STYPE_DISKTREE;
si2.shi2_permissions = 0;
si2.shi2_max_uses = SHI_USES_UNLIMITED;
if( ! bUnicodeRemark ) // Point to valid string or nothing
si2.shi2_remark = "\0\0";
else
si2.shi2_remark = bUnicodeRemark;
if( ! bUnicodePassword ) // Point to valid string or nothing
si2.shi2_passwd = "\0\0";
else
si2.shi2_passwd = bUnicodePassword;
hModule = LoadLibrary( "NETAPI32.DLL" ); // Win95 should be SVRAPI.DLL
status = 1; // Initialize to error state
if( hModule ) // Load the module
{ // If loaded, get function address
(DWORD)pNetShareAdd = (DWORD)GetProcAddress( hModule, "NetShareAdd" );
if( pNetShareAdd ) // And if that works, call it
status = pNetShareAdd( "", 2, (LPBYTE)&si2, &dwErr );
FreeLibrary( hModule );
}
if( bUnicodePassword ) // Free all used Unicode strings
GlobalFreePtr( bUnicodePassword );
if( bUnicodeRemark )
GlobalFreePtr( bUnicodeRemark );
GlobalFreePtr( bUnicodeShare );
GlobalFreePtr( bUnicodePath );
if( ! status ) // Return TRUE if no error, FALSE if error
return( TRUE );
return( FALSE );
}