Prehistory
Somehow took programmatically open access to the network resource. After reading (again) HELP from Delphi became clear that network administration functions of the family engaged in Net *. And in particular for opening, closing access to the network share, and retrieve or modify information about the functions it uses subfamily NetShare *. However, as it is written in the help, all of these features work only under WinNT. Unfortunately ...
But once Win'9x opens (closes) access, so you can do the same thing programmatically. And then began the search.
In the HELP says that C + + is necessary to apply a header module LmShare.h, which are function prototypes library netapi32.dll. Seeing this library utility tdump.exe (is in the directory Delphi_X \ Bin), I saw that the library netapi32.dll (for Win'9x) except one exported function netbios contains nothing more. Next turn ordinary text search "NetShareAdd" files *. Dll. Search yielded a result - among several libraries that string contains a library svrapi.dll.
Following the beaten path, ie through tdump.exe, saw that this library contains nearly all exported functions with names Net *. Hooray! A place where "the dog fumbled" found! It remains only to this dog to dig.
It is clear that without the knowledge of the prototypes of these functions themselves their names - empty the trash. Include searching the Internet line "svrapi". And here it is, the coveted module header! SvrApi.pas. Lies, darling on JEDI! Wrote his Vones Petr , for which he thanks a lot! In this module are the following classes of prototypes Net-functions:
ACCESS
SHARE
SESSION
CONNECTION
FILE
SERVER
SECURITY
Description Net-functions is given in the help of Delphi. Their work is the same for WinNT, and for Win'9x. However, for Win'9x use multiple other arguments. What will be discussed below.
Function NetShareAdd
All family NetShare *, and this:
Code:
NetShareAdd - provides access to a network resource
NetShareDel - block access to the network resource
NetShareEnum - shows the number of properties and resources with open access
NetShareGetInfo - provide full details of the open network share
NetShareSetInfo - change some of the values of open network resource
here I will not describe because intend to put these examples to work with all the features NetShare * on its website . Describe only one - NetShareAdd
So function NetShareAdd. Here is a prototype:
function NetShareAdd ( const pszServer: PChar; sLevel: SmallInt; pbBuffer:
Pointer; cbBuffer: Word): NET_API_STATUS; stdcall ;
Arguments description will be given below. Now consider how to connect this feature.
Connecting an external function
Without going into details, the connection of external functions is no big deal. In Unit.pas after describing the TForm class and implementation clauses to write:
Code:
function NetShareAdd (ServerName: PChar; Level: Integer; pbBuffer: Pointer;
BufferSize: Integer): Integer; stdcall ; external 'svrapi.dll';
What you should pay attention. First, I willingly replaced some types of variables on a more conventional Integer (although by and large not to do so). Secondly, stdcall - is a method of transmitting data through the stack used for Pascal. And thirdly, external 'svrapi.dll' - means that the function is in an external library called svrapi.dll.
Now the arguments.
Function Arguments
ServerName - network computer name, you can write to the local Nill.
What can be said about this argument. To work with the local machine no problem. For example, if the network name of the machine Toshiba, then this option must write '\ \ Toshiba' or specify Nill. But for a networked machine problems. NetShareAdd testing the network, I always get the result of the function value of 65, which means - "No network access." It turned out to allow access to the network for NetShare-functions should be "Allow remote management of this server" (done in the "Password" from the "Control Panel"). Then the Windows directory is assigned to the network name ADMIN $ and after the connection of the name as a network drive, "sesame" opens. All this can be done programmatically: using the function described open access named ADMIN $ to any directory, including non-existent (see below) and by using one of three WNetAddConnection network drive for this name. Then everything will work out with a bang.
Level - the level of administration. For WinNT used three levels of 1.2 and 502, should be used for Win'9x level 50.
pbBuffer - a pointer to a structure that will bring all the data needed to open access to the resource. This structure should stay in more detail. Here she is:
Code:
type
= packet TShareInfo50 Record
shi50_netname: array [0 .. LM20_NNLEN] of Char; / / network name
shi50_type: Byte; / / resource type
shi50_flags: Short; / / access flag
shi50_remark: PChar; / / Comment
shi50_path: PChar; / / path to the resource
shi50_rw_password: array [0 .. SHPWLEN] of Char; / / password full access
shi50_ro_password: array [0 .. SHPWLEN] of Char;
/ / password "read only" access
end ;
shi50_netname - network name, upon application which will be available to the network resource. Network name must be unique. LM20_NNLEN constant has a value of 12, ie network name must not be longer than 12 characters.
shi50_type - type of resource can have the following values:
STYPE_DISKTREE = 0; - Will open access to the directory;
STYPE_PRINTQ = 1; - Will open access to the printer;
There are two constants, but to be honest, I have not tested it:
STYPE_DEVICE = 2; - Will open access to the communication device;
STYPE_IPC = 3; - Access to the interprocess communication.
shi50_flags - access flag can have the following values:
SHI50F_RDONLY = $ 0001; - Read-only access;
SHI50F_FULL = $ 0002; - Full access;
SHI50F_DEPENDSON = SHI50F_RDONLY or SHI50F_FULL; - Access password is entered;
SHI50F_ACCESSMASK = SHI50F_RDONLY or SHI50F_FULL - access password is entered;
SHI50F_PERSIST = $ 0100; - Resource will be recorded in Registry and restart the computer access will be opened in the machine. For some reason Win'95 stored and accessed without specifying this parameter.
SHI50F_SYSTEM = $ 0200; - Explorer will not show that access to this resource is open.
shi50_remark - Comment
shi50_path - full physical path to the device. Here we must consider the following:
If the path to specify lowercase (small) letters, the Explorer will not show that access to the device is opened.
If you specify a nonexistent path, access to such a device would still be open. For example, if you open access to non-existent folder C: \ TEST333 and assign a network name TEST66, then in a networked environment will be seen the network name TEST66. If you then create a folder named TEST333, then this folder will appear under "blue pen".
shi50_rw_password - password for full access; shi50_ro_password - password "read only" where SHPWLEN = 8, ie maximum number of characters in a password given character number 0 is 9 pieces.
Finally, the last argument BufferSize - size of the buffer, which are necessary to open access to the data.
We now turn to the value returned by NetShareAdd .
Result function
If successful, the function returns 0. In case of failure, returns a numeric value. The processing of this value, in most cases allows localizing the cause of the failure.
Function NetShareAdd include types of errors (in my free translation):
Code:
NO_ERROR = 0; 'All right'
/ / of LmErr.pas:
NERR_BASE = 2100; basic error for NERR_;
NERR_NetNotStarted = NERR_BASE + 2 'Network Unavailable';
NERR_UnknownServer = NERR_BASE + 3 'Unknown host';
NERR_ServerNotStarted = NERR_BASE + 14 'Server does not work';
NERR_UnknownDevDir = NERR_BASE + 16 'A network device is missing';
NERR_RedirectedPath = NERR_BASE + 17 'Reassigning Device';
NERR_DuplicateShare = NERR_BASE + 18 'Network name already exists';
NERR_BufTooSmall = NERR_BASE + 23 'Buffer too small for the data';
NERR_NetNameNotFound = NERR_BASE + 210 'network name does not exist';
NERR_InvalidComputer = NERR_BASE + 251 'Invalid computer name';
NERR_ShareNotFound = NERR_BASE + 292 'Network device not found';
However, there are other errors. Somehow function SysErrorMessage (GetLastError) and WNetGetLastError working with NetShare * (at least for me) do not work, so the values of error codes are less than 2100, I took out the errors that are common to the entire operating system. (From Windows.pas
Code:
ERROR_NOT_ENOUGH_MEMORY = 8 'Memory';
ERROR_BAD_NETPATH = 53 'Invalid network name';
ERROR_NETNAME_DELETED = 64 'The specified network resource is no longer available';
ERROR_NETWORK_ACCESS_DENIED = 65 'No network access';
ERROR_BAD_DEV_TYPE = 66 'Invalid network resource type';
ERROR_BAD_NET_NAME = 67 'Not found network name';
ERROR_INVALID_PARAMETER = 87 'parameter is incorrect';
ERROR_INVALID_LEVEL = 124 'Invalid level administration';
Ie if the result of the function returns a number greater than 2100, then see module LmErr.pas, if less - the module Windows.pas.
In this kind of everything. But, it is better to see once than ... So let's see how it works in practice.
Example of NetShareAdd
For the directory C: \ Temp open access local machine named "TEST", the password is read "QWE", for full access "ASDF", commented "This is a network machine's commentary", with automatic access opening when the computer restarts. And at the same time close the access.
On the new form should put two buttons and lead Unit1.pas view in conformity with the code listed below.
Code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class (TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click (Sender: TObject);
procedure Button2Click (Sender: TObject);
Private
{Private declarations}
Public
declarations} {Public
end ;
/ / Include the two functions from the library svrapi.dll
function NetShareAdd (Servername: PChar; Level: Integer; Buffer: Pointer;
BufferSize: Integer): Integer; stdcall ; external 'svrapi.dll';
function NetShareDel (Servername: PChar; NetName: PChar; Reserved: DWORD): DWORD;
stdcall ; external 'svrapi.dll';
/ / Required constants
const
{see LmCons.pas}
LM20_NNLEN = 12;
SHPWLEN = 8;
SHI50F_RDONLY = 1;
SHI50F_FULL = 2;
STYPE_DISKTREE = 0;
SHI50F_PERSIST = $ 0100;
SHI50F_SYSTEM = $ 0200;
{See LmErr.pas}
NERR_BASE = 2100;
NERR_NetNotStarted = NERR_BASE + 2;
NERR_UnknownServer = NERR_BASE + 3;
NERR_ServerNotStarted = NERR_BASE + 14;
NERR_UnknownDevDir = NERR_BASE + 16;
NERR_RedirectedPath = NERR_BASE + 17;
NERR_DuplicateShare = NERR_BASE + 18;
NERR_BufTooSmall = NERR_BASE + 23;
NERR_NetNameNotFound = NERR_BASE + 210;
NERR_InvalidComputer = NERR_BASE + 251;
NERR_ShareNotFound = NERR_BASE + 292;
/ / Form a type of recording with the required parameters
type
= TShareInfo50 Record
shi50_netname: array [0 .. LM20_NNLEN] of Char; / / network name
shi50_type: Byte; / / resource type
shi50_flags: Short; / / access flag
shi50_remark: PChar; / / Comment
shi50_path: PChar; / / path to the resource
shi50_rw_password: array [0 .. SHPWLEN] of Char; / / password full access
shi50_ro_password: array [0 .. SHPWLEN] of Char;
/ / password "read only" access
end ; {Record}
var
Form1: TForm1;
Implementation
{$ R *. DFM}
procedure TForm1.Button1Click (Sender: TObject);
var
info50: TShareInfo50;
rc, cb: Integer;
ServerName, Path, NetName, ErrMes, ErrCap, Comment: string ;
MessIconBtn: Byte;
begin
/ / set the required parameters
ServerName: ='';
Path: = 'C: \ TEMP';
NetName: = 'TEST';
Comment: = 'This is a network machine'' s commentary';
/ / Fill the buffer
FillChar (info50, sizeof (info50), 0);
with info50 do
begin {With}
StrCopy (shi50_netname, PChar (NetName)); / / network name
shi50_type: = STYPE_DISKTREE; / / connect will drive
shi50_remark: = PChar (Comment); / / Comment
shi50_flags: = SHI50F_RDONLY or SHI50F_FULL / / password access is defined
or SHI50F_PERSIST; / / and is written in the Registry
shi50_path: = PChar (Path); / / path
StrPCopy (shi50_rw_password, 'ASDF'); / / password for full access
StrPCopy (shi50_ro_password, 'QWE'); / / password for the "read only"
end ; {With}
/ / Set the buffer size
cb: = sizeof (info50);
/ / Main function
rc: = NetShareAdd (PChar (ServerName), 50, @ info50, cb);
/ / Form the text messages about the success or error
ErrMes: = 'Device Access "' + NetName + '" open';
ErrCap: = 'All right!';
MessIconBtn: = MB_OK or MB_ICONINFORMATION;
/ / error checking
if RC <> 0 then
begin {error}
ErrCap: = 'error';
MessIconBtn: = MB_OK or MB_ICONERROR;
Case RC of
/ / decoding errors
ERROR_NOT_ENOUGH_MEMORY: ErrMes: = 'Out of memory';
ERROR_BAD_NETPATH: ErrMes: = '"' + Servername +
'"- Wrong network name';
ERROR_NETNAME_DELETED: ErrMes: = 'The specified network resource is no longer available';
ERROR_NETWORK_ACCESS_DENIED: ErrMes: = 'No network access';
ERROR_BAD_DEV_TYPE: ErrMes: = 'Wrong network resource type';
ERROR_BAD_NET_NAME: ErrMes: = 'Not found network name';
ERROR_INVALID_PARAMETER: ErrMes: = 'Invalid parameter';
ERROR_INVALID_LEVEL: ErrMes: = 'Wrong level administration';
NERR_InvalidComputer: ErrMes: = 'Invalid computer name';
NERR_UnknownServer: ErrMes: = 'Unknown host';
NERR_UnknownDevDir: ErrMes: = 'device "' + Path + '" missing';
NERR_ServerNotStarted: ErrMes: = 'Server does not work';
NERR_RedirectedPath: ErrMes: = 'reassignment path';
NERR_DuplicateShare: ErrMes: = 'Network name "' + NetName +
'' Already exists';
NERR_BufTooSmall: ErrMes: = 'Buffer too small for the data';
else
end ; } {Case
end ; {error}
/ / Issue a message
MessageBox (Application.Handle, PChar (ErrMes), PChar (ErrCap), MessIconBtn);
end ;
procedure TForm1.Button2Click (Sender: TObject);
var
rc: DWord;
Servername, NetName, ErrMes, ErrCap: string ;
MessIconBtn: Byte;
begin
ServerName: ='';
NetName: = 'TEST';
rc: = NetShareDel (PChar (ServerName), PChar (NetName), 0);
ErrMes: = 'Device Access "' + NetName + '" closed';
ErrCap: = 'All right!';
MessIconBtn: = MB_OK or MB_ICONINFORMATION;
if RC <> 0 then
begin {error}
/ / Error
ErrCap: = 'error';
MessIconBtn: = MB_OK or MB_ICONERROR;
Case RC of
/ / decoding errors
ERROR_BAD_NETPATH: ErrMes: = '"' + Servername +
'"- Wrong network name';
ERROR_INVALID_PARAMETER: ErrMes: = 'Invalid parameter';
NERR_NetNotStarted: ErrMes: = 'Network not available';
NERR_ServerNotStarted: ErrMes: = 'Server does not work';
NERR_NetNameNotFound: ErrMes: = 'The device does not exist';
NERR_ShareNotFound: ErrMes: = 'Network name "' + NetName + '" not found';
else
/ / look for errors or NetShareAdd
ErrMes: = 'An unknown network error';
end ; } {Case
end ; {error}
MessageBox (Application.Handle, PChar (ErrMes), PChar (ErrCap), MessIconBtn);
end ;
end .
Part 2 coming