{$X+,B-,V-} {essential compiler directives} UNIT nwServ; { nwServ unit as of 950301 / NwTP 0.6 API. (c) 1993,1995, R. Spronk } INTERFACE uses nwIntr,NwMisc,nwConn; Var result:word; { Primary Functions: Interrupt: Comments: * CheckConsolePrivileges (F217/C8) * ClearConnectionNumber (F217/D2) * DisableFileServerLogin (F217/CB) . DisableTransactionTracking (F217/CF) * DownFileServer (F217/D3) * EnableFileServerLogin (F217/CC) . EnableTransactionTracking (F217/D0) * GetConnectionsOpenFiles (F217/EB) GetConnectionsUsingAFile (F217/EC) * GetDiskUtilization (F217/0E) * GetFileServerDateAndTime (F214) * GetFileServerDescriptionStrings (F217/C9) * GetFileServerLoginStatus (F217/CD) * GetNetworkSerialNumber (F217/12) * GetFileServerInformation (F217/11) * SetFileServerDateAndTime (F217/CA) * VerifyNetworkSerialNumber (F217/0C) Secondary functions: * CheckNetwareVersion Not supported by netware 3.x: (2.x only) - GetBinderyObjectDiskSpaceLeft (F217/E6) (failed during testing) - GetConnectionsTaskInformation (E3../DA) - GetConnectionsUsageStats (E3../E5) - GetConnectionsUsingAFile (E3../DC) - GetDiskCacheStats (E3../D6) - GetDiskChannelStats (E3../D9) - GetDriveMappingTable (E3../D7) - GetFileServerLANIOStats (E3../E7) - GetFileServerMiscInformation (E3../E8) - GetFileSystemStats (E3../D4) - GetLANDriverConfigInfo (E3../E3) - GetLogicalRecordInformation (E3../E0) - GetLogicalRecordsByConnection (E3../DF) - GetPhysicalDiskStats (E3../D8) - GetPhysicalRecordLocksByFile (E3../DE) - GetPhysRecLocksByConnectAndFile (E3../DD) } Type TFileServerInformation =Record ServerName : string[48]; NetwareVersion : Byte; NetwareSubVersion : Byte; { 0..99 } ConnectionsMax : word; ConnectionsInUse : word; MaxConnVol : word; { max connected volumes } {---Advanced Netware 2.1x/3.x------------} OS_revision : byte; SFT_level : byte; TTS_level : byte; peak_conn_used : word; { max simult.used connections} accounting_version : byte; vap_version : byte; queuing_version : byte; print_server_version : byte; virtual_console_version : byte; security_restrictions_level : byte; Internetwork_bridge_version : byte; Undefined : Array [1..60] of Byte; End; Type TfileInfoRecord=record TaskNbr :Word; LockType :Byte; { 00 no lock; FE file lock; FF locked by Begin Share File Set } AccessFlag :Byte; LockFlag :Byte; VolNbr :Byte; { 0..31 } ParentEntryId:Longint; DirEntryId :Longint; ForkCount :Byte; NStype :Byte; FileName :String; end; TfileInfoRecList=array[1..28] of TfileInfoRecord; Type TfileUsageList=record UseCount :word; OpenCount :word; OpenForReadCount :word; OpenForWriteCount:word; DenyReadCount :word; DenyWriteCount :word; LockFlag :Byte; { boolean } NStype :Byte; { Fork Count = File siz? of NStype? } NbrOfRec :word; { max 70 } FileUsage:array[1..70] of record ConnNbr :word; TaskNbr :word; LockType :byte; AccessFlag:Byte; LockFlag :Byte; end; end; {F217/C8 [2.15c+]} FUNCTION CheckConsolePrivileges : Boolean; {F217/D2 [2.15c+]} Function ClearConnectionNumber(connectionNbr:byte):boolean; { Console Rights needed; -Terminates a connection. } {F217/CB [2.15c+]} FUNCTION DisableFileServerLogin : Boolean; {F217/CF [2.15c+]} FUNCTION DisableTransactionTracking : Boolean; {F217/D3 [2.15c+]} FUNCTION DownFileServer (ForceFlag : Boolean) : Boolean; {F217/CC [2.15c+]} FUNCTION EnableFileServerLogin : Boolean; {F217/D0 [2.15c+]} FUNCTION EnableTransactionTracking : Boolean; {F217/EB [3.0+]} FUNCTION GetConnectionsOpenFiles ( ConnNumber : Byte; {i/o:} var LastRecordSeen : word; {out:} var NbrOfRecords : word; var FileInfo : TfileInfoRecList ) : Boolean; {F217/0E [2.15c+]} FUNCTION GetDiskUtilization(volNbr:byte; objID:Longint; Var usedDirs,usedFiles,usedBlocks:Word ):Boolean; {F214 [2.15c+]} FUNCTION GetFileServerDateAndTime ( Var time:TnovTime): Boolean; {F217/C9 [2.15c+]} FUNCTION GetFileServerDescriptionStrings(Var companyName, VersionAndRevision,revisionDate, copyrightNotice:String ):Boolean; {F217/CD [2.15c+]} FUNCTION GetFileServerLoginStatus (Var LoginEnabled:Boolean): Boolean; { if Login is enabled then returns TRUE in LoginEnabled } {F217/12 [2.15c+]} Function GetNetworkSerialNumber(Var serialNbr:LongInt; Var ApplicNbr:Word ):Boolean; {return the serial number and application number for the software installed on the file server} {F217/11 [2.15c+]} Function GetFileServerInformation (Var serverInfo:TFileServerInformation):boolean; {determine the version of software installed on the file server and how it is configured} {F217/CA [2.15c+]} FUNCTION SetFileServerDateAndTime(time:TnovTime):Boolean; {need console operator privileges to do this} {F217/OC [2.15c+]} Function VerifyNetworkSerialNumber(serialNbr: LongInt ; Var ApplicNbr: Word ):Boolean; {if the network serial number to be verified is correct, the reply buffer will contain the corresponding application number } {*********************** Secondary Functions ******************************} { [1.x/2.x/3.x] } FUNCTION CheckNetwareVersion(MinimumVersion,MinimumSubVersion, MinimumRevision,MinimumSFT,MinimumTTS:word):Boolean; IMPLEMENTATION{=============================================================} {F217/D2 [2.15c+]} Function ClearConnectionNumber(connectionNbr:byte):boolean; { Console Rights needed; -Terminates a connection. } Type Treq=record len : word; subf: byte; _connNbr:byte; end; TPreq=^Treq; begin With TPreq(GlobalReqBuf)^ do begin len:=2; subf:=$D2; _connNbr:=connectionNbr end; F2SystemCall($17,SizeOf(Treq),0,result); ClearConnectionNumber:=(result=0); {result codes: 00 successful; C6 No Console Rights} end; {F214 [2.15c+]} FUNCTION GetFileServerDateAndTime ( Var time:TnovTime): Boolean; Type Trep=TnovTime; TPrep=^Trep; BEGIN F2SystemCall($14,0,SizeOf(Trep),result); Time:=TPrep(GlobalreplyBuf)^; if time.year>100 then time.year:=time.year-100; { year<80 : 21st century } result:=0; getFileServerDateAndTime:=TRUE; end; {F217/CA [2.15c+]} FUNCTION SetFileServerDateAndTime (time:TnovTime): Boolean; Type Treq=record Len:word; subF:byte; _time:TnovTime end; TPreq=^Treq; BEGIN { year<80 : 21st century } WITH TPreq(GlobalReqBuf)^ do begin Len:=SizeOf(Treq)-3; { dow is not a parameter } subF:=$CA; _time:=time; end; F2SystemCall($17,SizeOf(Treq),0,result); SetFileServerDateAndTime:=(Result=$00); { Resulcodes: $00 Success; $C6 No Console Operator Rights } end; {F217/11 [2.15c+]} Function GetFileServerInformation (Var serverInfo:TFileServerInformation):boolean; {determine the version of software installed on the file server and how it is configured} {SeeAlso: GetDiskUtilization, GetNetworkSerialNumber, GetFileServerLoginStatus, GetFileServerDateAndTime} Type TReq=Record Len : word; SubF : Byte; End; TRep=TFileServerInformation; TPreq=^Treq; TPrep=^Trep; Var t:word; Begin With TPreq(GlobalReqBuf)^ Do Begin Len := 1; SubF:= $11; End; F2SystemCall($17,SizeOf(Treq),SizeOf(Trep)-1,result); Move(GlobalReplyBuf^[1],GlobalReplyBuf^[2],SizeOf(Trep)-1); serverInfo:=TPrep(GlobalReplyBuf)^; With serverinfo do begin connectionsMax :=Swap(connectionsMax); { force lo-hi again } ConnectionsInUse:=Swap(connectionsInUse); MaxConnVol :=Swap(maxConnVol); peak_conn_used :=Swap(peak_conn_used); for t:=48 downto 1 do if serverInfo.serverName[t]=#0 then serverInfo.serverName[0]:=chr(t-1); end; GetFileServerInformation:=(result=0); End; {F217/C9 [2.15c+]} FUNCTION GetFileServerDescriptionStrings(Var companyName, VersionAndRevision,revisionDate, copyrightNotice:String ):Boolean; {SeeAlso: GetFileServerLoginStatus, GetFileServerInformation. } Type Treq=record len : word; subf: byte; end; Trep=record stuff : array [1..512] of byte; end; TPreq=^Treq; TPrep=^Trep; Var x,xofs:word; begin With TPreq(GlobalReqBuf)^ do begin len := 1; subf := $c9; end; F2SystemCall($17,SizeOf(Treq),SizeOf(Trep),result); companyName:=''; VersionAndRevision:=''; revisionDate:=''; copyrightNotice:=''; if result=$00 then with TPrep(GlobalReplyBuf)^ do begin x:=1;xofs:=x; while (stuff[x]<>$00) and (x<512) do inc(x); ZStrCopy(companyName,stuff[xofs],x-xofs); inc(x);xofs:=x; { skip 1 zero. ? skip more zero's? } While (stuff[x]<>$00) and (x<512) do inc(x); ZStrCopy(VersionAndRevision,stuff[xofs],x-xofs); inc(x);xofs:=x; While (stuff[x]<>$00) and (x<512) do inc(x); ZStrCopy(revisionDate,stuff[xofs],x-xofs); { mm/dd/yy } inc(x);xofs:=x; While (stuff[x]<>$00) and (x<512) do inc(x); ZStrCopy(copyrightNotice,stuff[xofs],x-xofs); end; GetFileServerDescriptionStrings:=(Result=$00); end; {F217/D3 [2.15c+]} FUNCTION DownFileServer (ForceFlag : Boolean) : Boolean; Type Treq=record len : word; subf : byte; flag : byte; end; TPreq=^Treq; BEGIN With TPreq(GlobalReqBuf)^ do begin len := 2; subf := $D3; if ForceFlag then flag := $FF { non-zero } else flag := $00; end; F2SystemCall($17,SizeOf(Treq),0,result); DownFileServer:=(result=0); { resultcodes: 00=successful; C6 No Console Rights ; FF Open Files} end; {F217/CF [3.x]} FUNCTION DisableTransactionTracking : Boolean; { Caller must have console-operator rights. } Type Treq=record len : word; subf: byte end; TPreq=^Treq; BEGIN With TPreq(GlobalReqBuf)^ do begin len := 1; subf:= $CF; end; F2SystemCall($17,SizeOf(Treq),0,result); DisableTransactionTracking:=(result=0); { resultcodes: 00=successful; C6 No Console Rights } end; {F217/D0 [3.x]} FUNCTION EnableTransactionTracking : Boolean; { Caller must have console-operator rights. } Type Treq=record len : word; subf: byte end; TPreq=^Treq; BEGIN With TPreq(GlobalReqBuf)^ do begin len := 1; subf:= $D0; end; F2SystemCall($17,SizeOf(Treq),0,result); EnableTransactionTracking:=(result=0); { resultcodes: 00=successful; C6 No Console Rights } end; {F217/CB [2.15c+]} FUNCTION DisableFileServerLogin : Boolean; { Caller must have console-operator rights. } Type Treq=record len : word; subf: byte end; TPreq=^Treq; BEGIN With TPreq(GlobalReqBuf)^ do begin len := 1; subf:= $CB; end; F2SystemCall($17,SizeOf(Treq),0,result); DisableFileServerLogin:=(result=0); { resultcodes: 00=successful; C6 No Console Rights } end; {F217/CC [2.15c+]} FUNCTION EnableFileServerLogin : Boolean; { Caller needs console-operator rights. } Type Treq=record len : word; subf: byte end; TPreq=^Treq; BEGIN With TPreq(GlobalReqBuf)^ do begin len := 1; subf:= $CC; end; F2SystemCall($17,SizeOf(Treq),0,result); EnableFileServerLogin:=(result=0); { resultcodes: 00=successful; C6 No Console Rights } end; {F217/CD [2.15c+]} FUNCTION GetFileServerLoginStatus( Var LoginEnabled:Boolean ): Boolean; { if Login is enabled then returns TRUE in LoginEnabled } { result byte: 00h - Success, C6h No Console Rights } { Caller must have operator status.} Type TReq=record Len : Word; SubF : Byte; end; TRep=record Flag : Byte; end; TPreq=^Treq; TPrep=^Trep; begin with TPreq(GlobalReqBuf)^ do begin Len := 1; SubF := $CD; end; F2SystemCall($17,SizeOf(Treq),SizeOf(Trep),result); LoginEnabled:=Boolean(TPrep(GlobalReplyBuf)^.Flag); GetFileServerLoginStatus := (result=0); end; {F217/C8 [2.15c+]} FUNCTION CheckConsolePrivileges : Boolean; Type TReq=record Len : Word; SubF : Byte; end; TPreq=^Treq; begin with TPReq(GlobalReqBuf)^ do begin Len := 1; SubF := $C8; end; F2SystemCall($17,SizeOf(Treq),0,result); CheckConsolePrivileges := (Result=$00); { result byte: 00h - Success, C6h No Console Rights } end; {F217/EB [3.0+]} FUNCTION GetConnectionsOpenFiles ( ConnNumber : Byte; {i/o:} var LastRecordSeen : word; {out:} var NbrOfRecords : word; var FileInfo : TfileInfoRecList ) : Boolean; { the calling workstation must have console operator privileges } { LastRecordSeen is an i/o parameter; -An initial value of 0 has to be supplied; -The function can be called until LastRecordSeen becomes 0, indicating the end of the FIR-list. to be called iteratively. } Type TReq=record len :word; subf :byte; logicalConnNbr:word; lastRecSeen :word; {lo-hi, $0000 on first call } end; TRep=record nextReqRec : word; { lo-hi, use as lastRecSeen in next iterative call } { $0000 if no more records } RecCount : word; FIRbuf:array[1..508] of byte; end; TPreq=^Treq; TPrep=^Trep; Var t,Foff:Word; begin With TPreq(GlobalReqBuf)^ do begin len:=sizeof(Treq)-2; subf:=$EB; logicalConnNbr:=connNumber; lastRecSeen:=LastRecordSeen; { force hi-lo } end; F2SystemCall($17,SizeOf(Treq),SizeOf(Trep),result); if result=$00 then with TPrep(GlobalReplyBuf)^ do begin { Copy recCount FIRs from FIRbuf to the FileInfo[] array } LastRecordSeen:=NextReqRec; NbrOfrecords:=RecCount; Foff:=0; For t:=1 to RecCount do begin Move(FIRbuf[1+Foff],FileInfo[t],17+FIRbuf[Foff+17]); inc(Foff,17+FIRbuf[Foff+17]); { Direntry and ParentEntry may have to be swapped lo-hi } end; end else begin NbrOfRecords:=0; LastRecordSeen:=0; end; GetConnectionsOpenFiles:=(result=$00); { errorcodes: $00 Success; $C6 no console privileges } end; {F217/EC } Function GetConnectionsUsingAFile(VolNbr:Byte; EntryId:Longint; NStype:byte; {i/o} Var LastRecordSeen:word; Var NbrOfRecords:Word; Var FileInfo:TfileUsageList):boolean; { This call returns all connection numbers using the file specified by the Volume Number and Directory Entry Id. } { !! UNDER CONSTRUCTION !! } Type TReq=record len :word; subf :byte; NStype :Byte; {= data stream type / Fork type } VolNbr :Byte; DirEntryId :Longint; LastRecSeen:Word; {initially set to 0} end; TRep=record NextRec :word; { iteration } UseCount :word; OpenCount :word; OpenForReadCount :word; OpenForWriteCount:word; DenyReadCount :word; DenyWriteCount :word; LockFlag :Byte; { boolean } NStype :Byte; { Fork Count -> ?? NStype } NbrOfRec :word; { max 70 } FileUsage:array[1..70] of record ConnNbr :word; TaskNbr :word; LockType :byte; AccessFlag:Byte; LockFlag :Byte; end; end; TPreq=^Treq; TPrep=^Trep; begin With TPreq(GlobalReqBuf)^ do begin len:=sizeof(Treq)-2; subf:=$EC; end; F2SystemCall($17,SizeOf(Treq),SizeOf(Trep),result); if result=$00 then with TPrep(GlobalReplyBuf)^ do begin end else begin NbrOfRecords:=0; LastRecordSeen:=0; end; GetConnectionsUsingAFile:=(result=$00); { errorcodes: $00 Success; $C6 no console privileges } end; {F217/0E [2.15c+]} FUNCTION GetDiskUtilization(volNbr:byte; objID:Longint; Var usedDirs,usedFiles,usedBlocks:Word ):Boolean; { SeeAlso: GetFileServerInformation,getBinderyObjectDiskSpaceLeft } Type TReq=record Len : Word; SubF : Byte; _volNbr:Byte; _objID:longInt; { hi-lo } end; TRep=record _volNbr:Byte; _objID:Longint; {hi-lo} _usedDirs, _usedFiles, _usedBlocks:Word; { all hi-lo } end; TPreq=^Treq; TPrep=^Trep; begin with TPReq(GlobalReqBuf)^ do begin Len := SizeOf(TReq)-2; SubF := $0E; _volNbr:=volNbr; _objID:=Lswap(objID); end; F2SystemCall($17,SizeOf(Treq),SizeOf(Trep),result); if result=$00 then begin with TPrep(GlobalReplyBuf)^ do begin usedDirs:=swap(_usedDirs); { force lo-hi } usedFiles:=swap(_usedFiles); { force lo-hi } usedBlocks:=swap(_usedBlocks);{ force lo-hi } end; end; GetDiskUtilization:=(result=$00); {Resultcodes: 00h successful; 98h volume doesn't exist 89h No Search Privileges F2h no Object read privileges } end; {F217/12 [2.15c+]} Function GetNetworkSerialNumber(Var serialNbr:LongInt; Var ApplicNbr:Word ):Boolean; {return the serial number and application number for the software installed on the file server} {SeeAlso: VerifyNetworkSerialNumber,GetFileServerInformation} Type TReq=record Len : Word; SubF : Byte; end; TRep=record _serNbr : LongInt; {hi-lo} _applicNbr: Word; {hi-lo} end; TPreq=^Treq; TPrep=^Trep; begin with TPreq(GlobalReqBuf)^ do begin Len := 1; SubF := $12; end; F2SystemCall($17,SizeOf(Treq),SizeOf(Trep),result); with TPrep(GlobalReplyBuf)^ do begin ApplicNbr:=swap(_applicNbr); { force lo-hi } serialNbr:=Lswap(_serNbr); { force lo-hi } end; GetNetworkSerialNumber := (result=0); end; {F217/OC [2.15c+]} Function VerifyNetworkSerialNumber(serialNbr: LongInt ; Var ApplicNbr: Word ):Boolean; {if the network serial number to be verified is correct, the reply buffer will contain the corresponding application number } {SeeAlso: GetNetworkSerialNumber} Type Treq=record Len : Word; SubF : Byte; _netwSerNbr: LongInt; {hi-lo} end; TRep=record _applicNbr: word; {hi-lo} end; TPreq=^Treq; TPrep=^Trep; begin with TPReq(GlobalReqBuf)^ do begin Len := 1; SubF := $0C; _netwSerNbr:=Lswap(serialNbr); end; F2SystemCall($17,SizeOf(Treq),SizeOf(Trep),result); with TPrep(GlobalReplyBuf)^ do begin ApplicNbr:=swap(_applicNbr); { force lo-hi } end; VerifyNetworkSerialNumber := (result=0); end; {****************** secondary functions ************************************} FUNCTION CheckNetwareVersion(MinimumVersion,MinimumSubVersion, MinimumRevision,MinimumSFT,MinimumTTS:word):Boolean; { checks if the current OS/TTS/SFT version is greater or equal to the minimal version } Var info:TFileServerInformation; res:boolean; begin IF GetFileServerInformation(info) then begin IF (info.NetwareVersion>MinimumVersion) then res:=true else if (info.NetwareVersion=MinimumVersion) AND (info.NetwareSubVersion>MinimumSubVersion) then res:=true else if (info.NetwareVersion=MinimumVersion) AND (info.NetwareSubVersion=MinimumSubVersion) AND (info.OS_Revision>=MinimumRevision) then res:=true else res:=false end else res:=false; CheckNetwareVersion:=res AND (info.SFT_Level>=MinimumSFT) AND (info.TTS_Level>=MinimumTTS) end; end. {unit nwServ}