На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Соблюдайте общие правила форума
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Указывайте точные версии Delphi и используемых сетевых библиотек.

Не приветствуется поднятие старых тем. Если ваш вопрос перекликается со старой темой, то для вопроса лучше создать новую тему, а старую указать в первом сообщении с описанием взаимосвязи.

Внимание:
попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...

Полезные ссылки:
user posted image MSDN Library user posted image FAQ раздела user posted image Поиск по разделу user posted image Как правильно задавать вопросы


Выразить свое отношение к модераторам раздела можно здесь: user posted image Krid, user posted image Rouse_

Модераторы: Krid, Rouse_
  
> Read-only шары
    Пользуюсь NetShareAdd из NETAPI32.DLL. В структуре SHARE_INFO_2 описано поле shi2_permissions, но как я понял его значение для всех систем семейства NT игнорируется:
    Цитата

    shi2_permissions
    Specifies a DWORD value that indicates the shared resource's permissions for servers running with share-level security. A server running user-level security ignores this member. This member can be one or more of the following values. Calls to the NetShareSetInfo function ignore this member.
    Note that the Windows Server 2003 family, Windows XP, Windows 2000, and Windows NT do not support share-level security.

    На практике так и есть, ставя любое другое разрешение помимо ACCESS_ALL папка все равно становится расшаренной на полный доступ. Вот в этом и состоит мой вопрос: как расшарить папку для доступа только для чтения из сети? Explorer ведь может.
        Цитата P.O.D @
        Расшарить папку (только для чтения)
        Тут vbs скрипт.

        Спасибо, но...
        Цитата Zoobastik @
        Хотя шарить так - это по моему извращение...

        Я тоже так считаю. Неужели это единственный способ?
          Сам нашел ответ на вопрос, привожу код, portions copyright Rouse_ (его код из NetMon я взял за основу) and Smike (до остального уже сам дошел, порывшись в MSDN и гугле). Кое-какие функции и константы распорошены по разным юнитам, в частности отсутствующих в дефолтной поставке - JclSysInfo (там только IsWinNT) и JclWin32 (некоторые константы).
          ExpandedWrap disabled
            uses
              Windows, SysUtils, JclSysInfo, AclApi, JclWin32;
             
            type
              TShareInfo502 = packed record
                shi502_netname : PWChar;
                shi502_type: DWORD;
                shi502_remark :PWChar;
                shi502_permissions: DWORD;
                shi502_max_uses : DWORD;
                shi502_current_uses : DWORD;
                shi502_path : PWChar;
                shi502_passwd : PWChar;
                shi502_reserved: DWORD;
                shi502_security_descriptor: PSECURITY_DESCRIPTOR;
              end;
             
              TShareInfo50 = packed record
                shi50_netname : array [0..12] of Char;
                shi50_type : Byte;
                shi50_flags : Word;
                shi50_remark : PChar;
                shi50_path : PChar;
                shi50_rw_password : array [0..8] of Char;
                shi50_ro_password : array [0..8] of Char;
              end;
             
            procedure ShareDirectory(const Directory: string);
            const
              STYPE_DISKTREE = 0;
              ACCESS_READ    = $1;
              SHI50F_RDONLY  = $1;
              ACL_REVISION   = 2;
            var
              FLibHandle : THandle;
              Share9x : TShareInfo50;
              ShareNT : TShareInfo502;
              TmpDir, TmpName: string;
              TmpDirNT, TmpNameNT: PWChar;
              TmpLength: Integer;
              NetShareAddNT: function(servername: PWideChar;
                                      level: DWORD;
                                      buf: Pointer;
                                      parm_err: LPDWORD): DWORD; stdcall;
             
              NetShareAdd: function (pszServer:Pchar;
                                     sLevel:Cardinal;
                                     pbBuffer:PChar;
                                     cbBuffer:Word):DWORD; stdcall;
              pSd: PSECURITY_DESCRIPTOR;
              pDacl: PACL;
              EveryoneSid, AdminSid: Pointer;
            begin
              TmpDir := ExcludeTrailingPathDelimiter(Directory);
              TmpName := ExtractFileName(TmpDir);
             
              if IsWinNT then begin //Код для NT
                FLibHandle := LoadLibrary('NETAPI32.DLL');
                if FLibHandle = 0 then Exit;
                NetShareAddNT := GetProcAddress(FLibHandle,'NetShareAdd');
                if not Assigned(NetShareAddNT) then
                begin
                  FreeLibrary(FLibHandle);
                  Exit;
                end;
                TmpLength := SizeOF(WideChar)*256; //Определяем необходимый размер
             
                GetMem(TmpNameNT, TmpLength); //Конвертируем в PWChar
                StringToWideChar(TmpName, TmpNameNT, TmpLength);
                ShareNT.shi502_netname := TmpNameNT; //Имя
             
                ShareNT.shi502_type := STYPE_DISKTREE; //Тип ресурса
                ShareNT.shi502_remark := ''; //Комментарий
                ShareNT.shi502_permissions := ACCESS_READ; //Доступ
                ShareNT.shi502_max_uses := DWORD(-1); //Кол-во максим. подключ.
                ShareNT.shi502_current_uses := 0; //Кол-во тек подкл.
             
                GetMem(TmpDirNT, TmpLength);
                StringToWideChar(TmpDir, TmpDirNT, TmpLength);
                ShareNT.shi502_path := TmpDirNT; //Путь к ресурсу
             
                ShareNT.shi502_passwd := ''; //Пароль
             
                ShareNT.shi502_reserved := 0;
             
                // Здесь начинается самое интересное - задаем разрешения :)
                GetMem(pDacl, 256);
                InitializeAcl(pDacl^, 256, ACL_REVISION);
                EveryoneSid := nil;
                AdminSid := nil;
                AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, EveryoneSid);
                AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, AdminSid);  
                AddAccessAllowedAce(pDacl^, ACL_REVISION, GENERIC_ALL, AdminSid);
                AddAccessAllowedAce(pDacl^, ACL_REVISION, (GENERIC_READ or GENERIC_EXECUTE or READ_CONTROL or STANDARD_RIGHTS_READ), EveryoneSid);
                GetMem(pSd, SECURITY_DESCRIPTOR_MIN_LENGTH);
                InitializeSecurityDescriptor(pSd, SECURITY_DESCRIPTOR_REVISION);
                SetSecurityDescriptorDacl(pSd, TRUE, pDacl, FALSE);
                ShareNT.shi502_security_descriptor := pSd;
             
                NetShareAddNT(nil, 502, @ShareNT, nil); //Добавляем ресурс
                
                if Assigned(EveryoneSid) then
                  FreeSid(EveryoneSid);
             
                if Assigned(AdminSid) then
                  FreeSid(EveryoneSid);      
                
                FreeMem (pDacl);    
                FreeMem (pSd);
                FreeMem (TmpNameNT); //освобождаем память
                FreeMem (TmpDirNT);
              end else begin
                FLibHandle := LoadLibrary('SVRAPI.DLL');
                if FLibHandle = 0 then Exit;
                NetShareAdd := GetProcAddress(FLibHandle,'NetShareAdd');
                if not Assigned(NetShareAdd) then
                begin
                  FreeLibrary(FLibHandle);
                  Exit;
                end;
                FillChar(Share9x.shi50_netname, SizeOf(Share9x.shi50_netname), #0);
                move(TmpName[1],Share9x.shi50_netname[0],Length(TmpName)); //Имя
                Share9x.shi50_type := STYPE_DISKTREE; //Тип ресурса
                Share9x.shi50_flags := SHI50F_RDONLY; //Доступ
                FillChar(Share9x.shi50_remark,
                  SizeOf(Share9x.shi50_remark), #0); //Комментарий
                FillChar(Share9x.shi50_path,
                  SizeOf(Share9x.shi50_path), #0);
                Share9x.shi50_path := PAnsiChar(TmpDir); //Путь к ресурсу
                FillChar(Share9x.shi50_rw_password,
                  SizeOf(Share9x.shi50_rw_password), #0); //Пароль полного доступа
                FillChar(Share9x.shi50_ro_password,
                  SizeOf(Share9x.shi50_ro_password), #0); //Пароль для чтения
                NetShareAdd(nil,50,@Share9x,SizeOf(Share9x));
              end;
              FreeLibrary(FLibHandle);
            end;
            Smike Круто ;)
              ExpandedWrap disabled
                    if Assigned(AdminSid) then
                      FreeSid(EveryoneSid);

              Конечно же FreeSid(AdminSid), copy-paste и спешка, блин.
                Так должно быть совсем нормально :) Никаких лишних юнитов и удобное использование. Можно наверно и в FAQ, раз вопрос повторяется.
                ExpandedWrap disabled
                  {*******************************************************}
                  {                                                       }
                  {       Добавление и удаление общих сетевых ресурсов    }
                  {                                                       }
                  { Copyright (c)                                         }
                  {    1998-2002 Rouse_                                   }
                  {              (базовый код, взят из примера NetMon)    }
                  {    2006 Smike                                         }
                  {              (- доработка для возможности создания    }
                  {                 ресурсов, открытых только для чтения  }
                  {                 под NT/2000/XP/2003,                  }
                  {               - небольшой рефакторинг ;) )            }
                  {                                                       }
                  {*******************************************************}
                   
                  unit Shares;
                   
                  interface
                   
                  uses
                    Windows, SysUtils, AclApi;
                   
                  function ShareDirectory(const Directory: string): DWORD;
                  function UnShareDirectory(const Directory: string): DWORD;
                   
                  implementation
                   
                  const
                    STYPE_DISKTREE = 0;
                   
                  function ShareDirectoryNT(const Directory, ShareName: string): DWORD;
                  type
                    TShareInfo502 = packed record
                      shi502_netname : PWChar;
                      shi502_type: DWORD;
                      shi502_remark :PWChar;
                      shi502_permissions: DWORD;
                      shi502_max_uses : DWORD;
                      shi502_current_uses : DWORD;
                      shi502_path : PWChar;
                      shi502_passwd : PWChar;
                      shi502_reserved: DWORD;
                      shi502_security_descriptor: PSECURITY_DESCRIPTOR;
                    end;
                  const
                    ACL_REVISION = 2;
                    SECURITY_WORLD_SID_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 1));
                    SECURITY_WORLD_RID = ($00000000);
                    SECURITY_NT_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5));
                    SECURITY_BUILTIN_DOMAIN_RID = ($00000020);
                    DOMAIN_ALIAS_RID_ADMINS = ($00000220);          
                  var
                    NetShareAddNT: function(servername: PWideChar;
                                            level: DWORD;
                                            buf: Pointer;
                                            parm_err: LPDWORD): DWORD; stdcall;
                    ShareNT : TShareInfo502;
                    FLibHandle: THandle;
                    TmpDirNT, TmpNameNT: PWChar;
                    TmpLength: Integer;
                    pSd: PSECURITY_DESCRIPTOR;
                    pDacl: PACL;
                    EveryoneSid, AdminSid: Pointer;  
                  begin
                    Result := DWORD(-1);
                    FLibHandle := LoadLibrary('NETAPI32.DLL');
                    if FLibHandle = 0 then Exit;
                    try
                      NetShareAddNT := GetProcAddress(FLibHandle,'NetShareAdd');
                      if not Assigned(NetShareAddNT) then Exit;
                      
                      TmpLength := SizeOf(WideChar) * 256; //Определяем необходимый размер
                   
                      GetMem(TmpNameNT, TmpLength); //Конвертируем в PWChar
                      StringToWideChar(ShareName, TmpNameNT, TmpLength);
                      ShareNT.shi502_netname := TmpNameNT; //Имя
                   
                      ShareNT.shi502_type := STYPE_DISKTREE; //Тип ресурса
                      ShareNT.shi502_remark := ''; //Комментарий
                      // В NT, 2000, XP, 2003 разрешения на уровне расшаренной папки не поддерживается
                      // Для этого задаем ниже атрибуты доступа на уровне групп
                      ShareNT.shi502_permissions := 0;
                      ShareNT.shi502_max_uses := DWORD(-1); //Кол-во максим. подключ.
                      ShareNT.shi502_current_uses := 0; //Кол-во тек подкл.
                   
                      GetMem(TmpDirNT, TmpLength);
                      StringToWideChar(Directory, TmpDirNT, TmpLength);
                      ShareNT.shi502_path := TmpDirNT; //Путь к ресурсу
                   
                      ShareNT.shi502_passwd := ''; //Пароль
                   
                      ShareNT.shi502_reserved := 0;
                   
                      // Здесь начинается самое интересное - задаем разрешения :)
                      GetMem(pDacl, 256);
                      InitializeAcl(pDacl^, 256, ACL_REVISION);
                      EveryoneSid := nil;
                      AdminSid := nil;
                      AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, EveryoneSid);
                      AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, AdminSid);
                      AddAccessAllowedAce(pDacl^, ACL_REVISION, GENERIC_ALL, AdminSid);
                      AddAccessAllowedAce(pDacl^, ACL_REVISION, (GENERIC_READ or GENERIC_EXECUTE or READ_CONTROL or STANDARD_RIGHTS_READ), EveryoneSid);
                      GetMem(pSd, SECURITY_DESCRIPTOR_MIN_LENGTH);
                      InitializeSecurityDescriptor(pSd, SECURITY_DESCRIPTOR_REVISION);
                      SetSecurityDescriptorDacl(pSd, TRUE, pDacl, FALSE);
                      ShareNT.shi502_security_descriptor := pSd;
                   
                      Result := NetShareAddNT(nil, 502, @ShareNT, nil); //Добавляем ресурс
                   
                      if Assigned(EveryoneSid) then
                        FreeSid(EveryoneSid);
                   
                      if Assigned(AdminSid) then
                        FreeSid(AdminSid);
                   
                      //освобождаем память
                      FreeMem(pDacl);
                      FreeMem(pSd);
                      FreeMem(TmpNameNT);
                      FreeMem(TmpDirNT);
                    finally
                      FreeLibrary(FLibHandle);
                    end;
                  end;
                   
                  function ShareDirectory9x(const Directory, ShareName: string): DWORD;
                  type
                    TShareInfo50 = packed record
                      shi50_netname : array [0..12] of Char;
                      shi50_type : Byte;
                      shi50_flags : Word;
                      shi50_remark : PChar;
                      shi50_path : PChar;
                      shi50_rw_password : array [0..8] of Char;
                      shi50_ro_password : array [0..8] of Char;
                    end;
                  const
                    SHI50F_RDONLY  = $1;
                  var
                    NetShareAdd: function(pszServer: PAnsiChar;
                                          sLevel: Cardinal;
                                          pbBuffer: PAnsiChar;
                                          cbBuffer: Word):DWORD; stdcall;
                    Share9x : TShareInfo50;
                    FLibHandle : THandle;  
                  begin
                    Result := DWORD(-1);
                    FLibHandle := LoadLibrary('SVRAPI.DLL');
                    if FLibHandle = 0 then Exit;
                    try
                      NetShareAdd := GetProcAddress(FLibHandle,'NetShareAdd');
                      if not Assigned(NetShareAdd) then Exit;
                   
                      FillChar(Share9x.shi50_netname, SizeOf(Share9x.shi50_netname), #0);
                      Move(ShareName[1], Share9x.shi50_netname[0], Length(ShareName)); //Имя
                      Share9x.shi50_type := STYPE_DISKTREE; //Тип ресурса
                      Share9x.shi50_flags := SHI50F_RDONLY; //Доступ
                      FillChar(Share9x.shi50_remark,
                        SizeOf(Share9x.shi50_remark), #0); //Комментарий
                      FillChar(Share9x.shi50_path,
                        SizeOf(Share9x.shi50_path), #0);
                      Share9x.shi50_path := PAnsiChar(Directory); //Путь к ресурсу
                      FillChar(Share9x.shi50_rw_password,
                        SizeOf(Share9x.shi50_rw_password), #0); //Пароль полного доступа
                      FillChar(Share9x.shi50_ro_password,
                        SizeOf(Share9x.shi50_ro_password), #0); //Пароль для чтения
                      Result := NetShareAdd(nil, 50, @Share9x, SizeOf(Share9x));
                    finally
                      FreeLibrary(FLibHandle);
                    end;
                  end;
                   
                  function ShareDirectory(const Directory: string): DWORD;
                  var
                    ShareDir, ShareName: string;
                  begin
                    ShareDir := ExcludeTrailingPathDelimiter(Directory);
                    ShareName := ExtractFileName(ShareDir);
                   
                    if Win32Platform = VER_PLATFORM_WIN32_NT then
                      Result := ShareDirectoryNT(ShareDir, ShareName)
                    else
                      Result := ShareDirectory9x(ShareDir, ShareName);
                  end;
                   
                  function UnShareDirectoryNT(const ShareName: string): DWORD;
                  var
                    FLibHandle : THandle;
                    NameNT: PWChar;
                    NetShareDelNT: function(servername: PWideChar;
                                            netname: PWideChar;
                                            reserved: DWORD): LongInt; stdcall;
                    Size: Integer;
                  begin
                    Result := DWORD(-1);
                    FLibHandle := LoadLibrary('NETAPI32.DLL');
                    if FLibHandle = 0 then Exit;
                    try
                      NetShareDelNT := GetProcAddress(FLibHandle, 'NetShareDel');
                      if not Assigned(NetShareDelNT) then //Проверка
                      begin
                        FreeLibrary(FLibHandle);
                        Exit;
                      end;
                      Size := SizeOf(WideChar) * 256;
                      GetMem(NameNT, Size);  //Выделяем память под переменную
                      StringToWideChar(ShareName, NameNT, Size); //Преобразуем в PWideChar
                      NetShareDelNT(nil, NameNT, 0);   //Удаляем ресурс
                      FreeMem(NameNT);  //Освобождаем память
                    finally
                      FreeLibrary(FLibHandle);
                    end;
                  end;
                   
                  function UnShareDirectory9x(const ShareName: string): DWORD;
                  var
                    FLibHandle: THandle;
                    Name9x: array [0..12] of Char;
                    NetShareDel: function(pszServer,
                                          pszNetName: PChar;
                                          usReserved: Word): DWORD; stdcall;
                  begin
                    Result := DWORD(-1);
                    FLibHandle := LoadLibrary('SVRAPI.DLL');
                    if FLibHandle = 0 then Exit;
                    try
                      NetShareDel := GetProcAddress(FLibHandle,'NetShareDel');
                      if not Assigned(NetShareDel) then Exit;
                      FillChar(Name9x, SizeOf(Name9x), #0); //Очищаем массив
                      Move(ShareName[1], Name9x[0], Length(ShareName)); //Заполняем массив
                      Result := NetShareDel(nil, @Name9x, 0); //Удаляем ресурс
                    finally
                      FreeLibrary(FLibHandle);
                    end;
                  end;
                   
                  function UnShareDirectory(const Directory: string): DWORD;
                  var
                    ShareName: string;
                  begin
                    ShareName := ExtractFileName(ExcludeTrailingPathDelimiter(Directory));
                   
                    if Win32Platform = VER_PLATFORM_WIN32_NT then       //Код для NT
                      Result := UnShareDirectoryNT(ShareName)
                    else                                                //Код для 9х-Ме
                      Result := UnShareDirectory9x(ShareName);
                  end;
                   
                  end.
                Сообщение отредактировано: Smike -
                  Угу, все хорошо, только я очень много раз говорил что все это делается через выставление дескрипторов безопасности, странно что не нашел мои сообщения :) Быстрее бы определился с выбором метода :)
                    Я забыл, что в 98-ой разрешений как таковых не существует. Есть только фйлажок "разрешить изменение файлов по сети".
                    1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0347 ]   [ 15 queries used ]   [ Generated: 13.07.25, 20:19 GMT ]