Как расшарить папку

ОГЛАВЛЕНИЕ

Вариант 1 (All Systems)

// Две функции: 1)Разрешает общий доступ к папке. 2) Запрещает его.
// Работают под Win9x/ME/NT/2000/XP
// Кодирование на WIN_32_API
// Компилятор BC++ 5.01
#define _UNICODE
// Кроме прочего нужно добавить нижеследующие строчки
#include <lm.h>
// svrapi.h не включать!
// Кусок из файла SVRAPI.H
// т.к. подключить его полностью невозможно
#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

struct share_info_50
{
   
char shi50_netname[LM20_NNLEN+1];    /* share name */
   unsigned char shi50_type;                 /* see below */
   unsigned short shi50_flags;                /* see below */
   char FAR * shi50_remark;                 /* ANSI comment string */
   char FAR * shi50_path;                     /* shared resource */
   char shi50_rw_password[SHPWLEN+1]; /* read-write password (share-level security) */
   char shi50_ro_password[SHPWLEN+1]; /* read-only password (share-level security) */
}; /* share_info_50 */

// Описание функций
BOOL CrShare(HWND, char*, char*, WORD);// Расшаривает папку. При успехе возвращает TRUE
BOOL DelShare(HWND, char*, WORD);// Запрещает общий доступ. При успехе возвращает TRUE

// Name - локальный путь к расшарив. папке. Последн. символ не должен быть '\'
// NetName - имя будущего общего ресурса. Длина имени меньше LM20_NNLEN
// WORD WinVer содержит версию Windows. WINNT - предопределенная в программе константа.

BOOL CrShare(HWND hwnd, char* Name, char* NetName, WORD WinVer)
{
   
HINSTANCE hIn;
   
HANDLE hShareAdd;
   
DWORD nLevel;
   
NET_API_STATUS nStatus;
   
DWORD Error;
   
char Str[MAX_PATH+80], BufErr[80];
   
char *sTitle = "Функция предоставления общего доступа";

   
CharUpper(Name); // Преобразование в верхний регистр внесено в тело функции по просьбе klep-а
   
CharUpper(NetName); // Преобразование в верхний регистр внесено в тело функции по просьбе klep-а

   
if(WinVer == WINNT)
   {
// Если NT/2000/XP
       
typedef NET_API_STATUS (*SHAREADDNT)(LPWSTR servername, DWORD level, LPBYTE buf, LPDWORD parm_err);
       
SHAREADDNT pShareAdd;
       
SHARE_INFO_502 si;
       
WCHAR wsName[MAX_PATH], wsNetName[MAX_PATH], wsRemark, wsPasswd;

// Преобразуем в UNICODE
       
if(!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, NetName, -1, wsNetName, MAX_PATH))
       {
           
Error = GetLastError();
           
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, Error, LANG_SYSTEM_DEFAULT, BufErr, 80, NULL);
           
sprintf(Str, "Затрудняюсь преобразовать в UNICODE сетевое имя папки.\nОшибка %u: %s", Error, BufErr);
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
return FALSE;
       };

       
if(!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Name, -1, wsName, MAX_PATH))
       {
           
Error = GetLastError();
           
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, Error, LANG_SYSTEM_DEFAULT, BufErr, 80, NULL);
           
sprintf(Str, "Затрудняюсь преобразовать в UNICODE путь к папке.\nОшибка %u: %s", Error, BufErr);
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
return FALSE;
       };

       
wsRemark = (WCHAR)0;
       
wsPasswd = (WCHAR)0;
       
memset(&si,0,sizeof(SHARE_INFO_502));

       
nLevel = 502;
       
si.shi502_netname = (LPTSTR)wsNetName;
       
si.shi502_type = STYPE_DISKTREE;
       
si.shi502_remark = (LPTSTR)&wsRemark;
       
si.shi502_permissions = ACCESS_ALL;
       
si.shi502_max_uses = -1;
       
si.shi502_current_uses = 0;
       
si.shi502_path = (LPTSTR)wsName;
       
si.shi502_passwd = (LPTSTR)&wsPasswd;
       
si.shi502_reserved = 0;
       
si.shi502_security_descriptor = NULL;

       
hIn = LoadLibrary("NETAPI32.DLL");
       
if(hIn == NULL)
       {
           
sprintf(Str, "Затрудняюсь загрузить библиотеку NETAPI32.DLL");
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
return FALSE;
       };

       
hShareAdd = GetModuleHandle("NETAPI32.DLL");
       
if(hShareAdd)
       {
           
pShareAdd = (SHAREADDNT)GetProcAddress((HMODULE)hShareAdd, "NetShareAdd");

           
if(!pShareAdd)
           {
               
MessageBox(hwnd,
"Затрудняюсь получить адрес функции NetShareAdd в NETAPI32.DLL", sTitle, MB_SYSTEMMODAL|MB_OK);
               
CloseHandle(hShareAdd);
               
FreeLibrary(hIn);
               
return FALSE;
           };
       }
       
else
       
{
           
Error = GetLastError();
           
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, Error, LANG_SYSTEM_DEFAULT, BufErr, 80, NULL);
           
sprintf(Str, "Затрудняюсь получить указатель на NETAPI32.DLL\nОшибка %u: %s", Error, BufErr);
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
FreeLibrary(hIn);
           
return FALSE;
       }
       
nStatus = pShareAdd(NULL, nLevel, (LPBYTE)&si, NULL);

       
if(nStatus! = NERR_Success)
       {
           
sprintf(Str, "Затрудняюсь открыть общий доступ к папке %s\nОшибка: %u", Name, nStatus);

           
if(nStatus == NERR_DuplicateShare) // Шареное имя уже есть точно такое же
               
strcat(Str, "\nСетевое имя уже существует.");

           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
CloseHandle(hShareAdd);
           
FreeLibrary(hIn);
           
return FALSE;
       };

       
CloseHandle(hShareAdd);
       
FreeLibrary(hIn);
   }
   
else
   
{     // Win9x
       
typedef NET_API_STATUS (*SHAREADD)(char* servername, short level, char* buf, unsigned short parm_err);
       
SHAREADD pSvrApi;
       
struct share_info_50 si50;
       
DWORD SizeSI50;
       
CHAR sRemark;

       
SizeSI50 = sizeof(struct share_info_50);
       
memset(&si50,0,SizeSI50);
       
sRemark=(CHAR)0;
       
nLevel = 50;
       
strcpy(si50.shi50_netname, NetName);
       
si50.shi50_type = STYPE_DISKTREE;
       
si50.shi50_flags = SHI50F_FULL|SHI50F_PERSIST;
//        si50.shi50_remark = NULL;                                        BUG в Win98. Выявлен   klep-ом
       
si50.shi50_remark=(LPTSTR)&sRemark;   // Решение найденное klep-ом и мной :)
       
si50.shi50_path = Name;
       
si50.shi50_rw_password[0] = '\0';
       
si50.shi50_ro_password[0] = '\0';
       
hIn = LoadLibrary("SVRAPI.DLL");

       
if(hIn == NULL)
       {
           
sprintf(Str, "Затрудняюсь загрузить библиотеку SVRAPI.DLL");
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
return FALSE;
       };

       
hShareAdd = GetModuleHandle("SVRAPI.DLL");

       
if(hShareAdd)
       {
           
pSvrApi = (SHAREADD)GetProcAddress((HMODULE)hShareAdd, "NetShareAdd");

           
if(!pSvrApi)
           {
               
MessageBox(hwnd,
"Затрудняюсь получить адрес функции NetShareAdd в SVRAPI.DLL", sTitle, MB_SYSTEMMODAL|MB_OK);
               
CloseHandle(hShareAdd);
               
FreeLibrary(hIn);
               
return FALSE;
           };
       }
       
else
       
{
           
Error = GetLastError();
           
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, Error, LANG_SYSTEM_DEFAULT, BufErr, 80, NULL);
           
sprintf(Str, "Затрудняюсь получить указатель на SVRAPI.DLL\nОшибка %u: %s", Error, BufErr);
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
FreeLibrary(hIn);
           
return FALSE;
       }

       
nStatus = pSvrApi(NULL, (short)nLevel, (char*)&si50, (unsigned short)SizeSI50);

       
if(nStatus! = NERR_Success)
       {
           
sprintf(Str, "Затрудняюсь открыть общий доступ к папке %s\nОшибка: %u", Name, nStatus);

           
if(nStatus == NERR_DuplicateShare) // Шареное имя уже есть точно такое же
               
strcat(Str, "\nСетевое имя уже существует.");

           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
CloseHandle(hShareAdd);
           
FreeLibrary(hIn);
           
return FALSE;
   };

   
CloseHandle(hShareAdd);
   
FreeLibrary(hIn);
}
return TRUE;
}

// NetName - имя существующего общего ресурса.  Длина имени меньше LM20_NNLEN
// WORD WinVer содержит версию Windows. WINNT - предопределенная в программе константа.

BOOL DelShare(HWND hwnd, char* NetName, WORD WinVer)
{
   
HINSTANCE hIn;
   
HANDLE hShareDel;
   
NET_API_STATUS nStatus;
   
DWORD Error;
   
char Str[MAX_PATH+80], BufErr[80];
   
char *sTitle = "Функция отмены общего доступа";

   
CharUpper(NetName); // Преобразование в верхний регистр внесено в тело функции по просьбе klep-а

   
if(WinVer == WINNT)
   {
       
typedef NET_API_STATUS (*SHAREDELNT)(LPWSTR servername, LPWSTR netname, DWORD parm);
       
SHAREDELNT pShareDel;
       
WCHAR wsNetName[MAX_PATH];

// Преобразуем в UNICODE
       
if(!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, NetName, -1, wsNetName, MAX_PATH))
       {
           
Error = GetLastError();
           
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, Error, LANG_SYSTEM_DEFAULT, BufErr, 80, NULL);
           
sprintf(Str, "Затрудняюсь преобразовать в UNICODE сетевое имя папки.\nОшибка %u: %s", Error, BufErr);
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
return FALSE;
       };

       
hIn = LoadLibrary("NETAPI32.DLL");

       
if(hIn == NULL)
       {
           
sprintf(Str, "Затрудняюсь загрузить библиотеку NETAPI32.DLL");
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
return FALSE;
       };

       
hShareDel = GetModuleHandle("NETAPI32.DLL");

       
if(hShareDel)
       {
           
pShareDel = (SHAREDELNT)GetProcAddress((HMODULE)hShareDel, "NetShareDel");

           
if(!pShareDel)
           {
               
MessageBox(
hwnd, "Затрудняюсь получить адрес функции NetShareDel в NETAPI32.DLL", sTitle, MB_SYSTEMMODAL|MB_OK);
               
CloseHandle(hShareDel);
               
FreeLibrary(hIn);
               
return FALSE;
           };
       }
       
else
       
{
           
Error = GetLastError();
           
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, Error, LANG_SYSTEM_DEFAULT, BufErr, 80, NULL);
           
sprintf(Str, "Затрудняюсь получить указатель на NETAPI32.DLL\nОшибка %u: %s", Error, BufErr);
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
FreeLibrary(hIn);
           
return FALSE;
       }

       
nStatus = pShareDel(NULL, wsNetName, 0);

       
if(nStatus! = NERR_Success)         {
           
sprintf(Str, "Затрудняюсь закрыть общий доступ к ресурсу %s\nОшибка сети : %u", NetName, nStatus);
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
CloseHandle(hShareDel);
           
FreeLibrary(hIn);
           
return FALSE;
       };
   }
   
else
   
{
// Win9x
       
typedef NET_API_STATUS (*SHAREDEL)(LPTSTR servername, LPTSTR netname, DWORD parm);
       
SHAREDEL pSvrApi;

       
hIn = LoadLibrary("SVRAPI.DLL");
       
if(hIn == NULL)
       {
           
sprintf(Str, "Затрудняюсь загрузить библиотеку SVRAPI.DLL");
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
return FALSE;
       };

       
hShareDel = GetModuleHandle("SVRAPI.DLL");

       
if(hShareDel)
       {
           
pSvrApi = (SHAREDEL)GetProcAddress((HMODULE)hShareDel, "NetShareDel");

           
if(!pSvrApi)
           {
               
MessageBox(
hwnd, "Затрудняюсь получить адрес функции NetShareDel в SVRAPI.DLL", sTitle, MB_SYSTEMMODAL|MB_OK);
               
CloseHandle(hShareDel);
               
FreeLibrary(hIn);
               
return FALSE;
           };
       }
       
else
       
{
           
Error = GetLastError();
           
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, Error, LANG_SYSTEM_DEFAULT, BufErr, 80, NULL);
           
sprintf(Str, "Затрудняюсь получить указатель на SVRAPI.DLL\nОшибка %u: %s", Error, BufErr);
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
FreeLibrary(hIn);
           
return FALSE;
       }

       
nStatus = pSvrApi(NULL, NetName, 0);
       
if(nStatus! = NERR_Success)
       {
           
sprintf(Str, "Затрудняюсь закрыть общий доступ к ресурсу %s\nОшибка: %u", NetName, nStatus);
           
MessageBox(hwnd, Str, sTitle, MB_SYSTEMMODAL|MB_OK);
           
CloseHandle(hShareDel);
           
FreeLibrary(hIn);
           
return FALSE;
       };
   }

   
CloseHandle(hShareDel);
   
FreeLibrary(hIn);
   
return TRUE;
}


 

Вариант 2 (NT)

// Открытие общего доступа к папке в WinNT, Win2000
// Один из самых простых способов по критерию трудозатрат программиста
// Для организации общего доступа используем командный процессор и команду net.
// С этой целью в командной строке следовало бы написать, например :
// net share sharefold=d:\temp\myserv
// Вот и реализуем этот метод через функцию на языке С
// Полное описание net share смотри по команде net help share

#include <stdlib.h>
// Описание функции
BOOL OpenShareNT(char* NetName, char* LocalName);
// В случае успеха возвращает TRUE, иначе FALSE.
// Первый параметр: LocalName - полный локальный путь к "расшариваемой" папке
// например "d:\\temp\\myserv" (Внимание! Путь не должен заканчиваться символом '\\')
// Второй параметр: NetName - имя, которое будет видно в сети (например "sharefold")

BOOL OpenShareNT(char* LocalName, char* NetName)
{
   
BOOL AddShare=FALSE;
   
char Str[MAX_PATH];
   
int Error;
// Проверим доступен ли командный процессор
   
Error=system(NULL);

   
if(Error < 0)
   {
    
// Обработчик ошибки: Командный процессор Windows недоступен.
   
}
   
else
   
{
       
sprintf(Str, "net share %s=%s", NetName, LocalName);
// При исполнении системной команды мелькнет черный экран - не пугайтесь :)
       
Error=system(Str);

       
if(Error < 0)
       {
        
// Обработчик ошибки: Невозможно открыть Общий доступ к папке.
       
}
       
else AddShare=TRUE; // Успешно
   
}
   
return AddShare;
}

// Закрытие общего доступа к папке в WinNT, Win2000
#include <stdlib.h>
// Описание функции
BOOL CloseShareNT(char* NetName);
// В случае успеха возвращает TRUE, иначе FALSE.
// Параметр: NetName - существующее сетевое имя

BOOL CloseShareNT(char* NetName)
{
   
BOOL CloseShare=FALSE;

   
char Str[MAX_PATH];
   
int Error;
// Проверим доступен ли командный процессор
   
Error=system(NULL);

   
if(Error < 0)
   {
    
// Обработчик ошибки: Командный процессор Windows недоступен.
   
}
   
else
   
{
       
sprintf(Str, "net share %s /DELETE", NetName);
// При исполнении системной команды мелькнет черный экран - не пугайтесь :)
       
Error=system(Str);
       
if(Error < 0)
       {
        
// Обработчик ошибки: Невозможно закрыть Общий доступ к папке.
       
}
       
else CloseShare=TRUE; // Успешно
   
}
   
return CloseShare;
}

Очевидно, что обе функции легко объединить в одну, и добавив третий параметр в список параметров первой функции, анализировать действие, толи открывать доступ, толи закрывать.


Вариант 3

Расшарить папку в NT/2000/XP:

Пользуем NetShareAdd
Declared in Lmshare.h
Use Netapi32.lib

NET_API_STATUS res; 
SHARE_INFO_2 inf;

memset(&inf, 0, sizeof(inf)); //Обнуляем структуру
inf.shi2_netname = _T("TEST_TEMP"); // Имя шаринга
inf.shi2_type = STYPE_DISKTREE; // расшариваем папку
inf.shi2_remark = _T("TeSt"); //Примечание. Хорошо наблюдается из консоли 'net share'
inf.shi2_permissions = ACCESS_READ|ACCESS_EXEC; //Доступ на чтение и исполнение
inf.shi2_max_uses = 4; //Ограничение на макс. кол-во подключеных юзеров
inf.shi2_path = _T("C:\\temp"); //Собственно папка, которую расшариваем
inf.shi2_passwd = NULL; // Без пароля
res=NetShareAdd(NULL, //LocalComputer
                   
2,
                   (
LPBYTE) &inf,
                   
NULL); //Не хотим знать доп. инф. об ошибке

if(res==NERR_Success)     return; //Всё получилось, выходим.
Ну вот, примерно так. Для 9х там по-другому, написать могу, но протестить негде.