SWAGOLX.EXE (c) 1993 GDSOFT ALL RIGHTS RESERVED 00019 NOVELL/LANTASTIC NETWORK ROUTINES 1 05-28-9313:52ALL SWAG SUPPORT TEAM DETCNETX.PAS IMPORT 13 {π▒i'm trying to find a method by which i can, from within a TP Program,π▒detect whether or not the NetWare shell has been loaded (Net3, NetX, orπ▒whatever); i've figured out how to determine if IPX is running, butπ▒can't seem to nail down the shell; the general idea is to detect IPX,π▒detect the shell, determine whether or not the user is logged in, and ifπ▒not, give them the oppurtUnity to do so; i've got most of the restπ▒figured out, but can't find the shell; any help would be greatlyπ▒appreciatedππTry Interrupt 21h, Function EAh, GetShellVersion;π}ππUsesπ {$IFDEF DPMI}π WinDos;π {$ELSE}π Dos;π {$endIF}πVarπ vOS,π vHardwareType,π vShellMajorVer,π vShellMinorVer,π vShellType,π vShellRevision : Byte;π {$IFDEF DPMI}π vRegs : tRegisters;π {$ELSE}π vRegs : Registers;π {$endIF}ππProcedure GetShellVersion;πbeginπ vOS := 0;π vHardwareType := 0;π vShellMajorVer := 0;π vShellMinorVer := 0;π vShellType := 0;π vShellRevision := 0;π FillChar(vRegs, SizeOf(vRegs), 0);π With vRegs DOπ beginπ AH := $EA;π Intr($21, vRegs);π vOS := AH; (* $00 = MS-Dos *)π vHardwareType := AL; (* $00 = PC, $01 = Victor 9000 *)π vShellMajorVer := BH;π vShellMinorVer := BL;π vShellType := CH; (* $00 = conventional memory *)π (* $01 = expanded memory *)π (* $02 = extended memory *)π vShellRevision := CL;π end;πend;ππbeginπ GetShellVersion;π Writeln(vOS);π Readln;πend. 2 05-28-9313:52ALL SWAG SUPPORT TEAM GET-ID1.PAS IMPORT 24 { TS> Can anybody help me finding the interrupt For gettingπ TS> a novell current user_name and the current station adress ??π}πProcedure GetConnectionInfoπ(Var LogicalStationNo: Integer; Var Name: String; Var HEX_ID: String;π Var ConnType : Integer; Var DateTime : String; Var retcode:Integer);ππVarπ Reg : Registers;π I,X : Integer;π RequestBuffer : Recordπ PacketLength : Integer;π FunctionVal : Byte;π ConnectionNo : Byte;π end;π ReplyBuffer : Recordπ ReturnLength : Integer;π UniqueID1 : Packed Array [1..2] of Byte;π UniqueID2 : Packed Array [1..2] of Byte;π ConnType : Packed Array [1..2] of Byte;π ObjectName : Packed Array [1..48] of Byte;π LoginTime : Packed Array [1..8] of Byte;π end;π Month : String[3];π Year,π Day,π Hour,π Minute : String[2];ππbeginπ With RequestBuffer Do beginπ PacketLength := 2;π FunctionVal := 22; { 22 = Get Station Info }π ConnectionNo := LogicalStationNo;π end;π ReplyBuffer.ReturnLength := 62;π With Reg Do beginπ Ah := $e3;π Ds := Seg(RequestBuffer);π Si := ofs(RequestBuffer);π Es := Seg(ReplyBuffer);π Di := ofs(ReplyBuffer);π end;π MsDos(Reg);π name := '';π hex_id := '';π connType := 0;π datetime := '';π if Reg.al = 0 then beginπ With ReplyBuffer Do beginπ I := 1;π While (I <= 48) and (ObjectName[I] <> 0) Do beginπ Name[I] := Chr(Objectname[I]);π I := I + 1;π end { While };π Name[0] := Chr(I - 1);π if name<>'' thenπ beginπ Str(LoginTime[1]:2,Year);π Month := Months[LoginTime[2]];π Str(LoginTime[3]:2,Day);π Str(LoginTime[4]:2,Hour);π Str(LoginTime[5]:2,Minute);π if Day[1] = ' ' then Day[1] := '0';π if Hour[1] = ' ' then Hour[1] := '0';π if Minute[1] = ' ' then Minute[1] := '0';π DateTime := Day+'-'+Month+'-'+Year+' ' + Hour + ':' + Minute;π end;π end { With };π end;π retcode := reg.al;π if name<>'' thenπ beginπ hex_id := '';π hex_id := hexdigits[replybuffer.uniqueid1[1] shr 4];π hex_id := hex_id + hexdigits[replybuffer.uniqueid1[1] and $0F];π hex_id := hex_id + hexdigits[replybuffer.uniqueid1[2] shr 4];π hex_id := hex_id + hexdigits[replybuffer.uniqueid1[2] and $0F];π hex_id := hex_id + hexdigits[replybuffer.uniqueid2[1] shr 4];π hex_id := hex_id + hexdigits[replybuffer.uniqueid2[1] and $0F];π hex_id := hex_id + hexdigits[replybuffer.uniqueid2[2] shr 4];π hex_id := hex_id + hexdigits[replybuffer.uniqueid2[2] and $0F];π ConnType := replybuffer.connType[2];π { Now we chop off leading zeros }π While hex_id[1]='0' do hex_id := copy(hex_id,2,length(hex_id));π end;πend; { GetConnectInfo };ππ 3 05-28-9313:52ALL SWAG SUPPORT TEAM GET-ID2.PAS IMPORT 19 {π> Okay, here goes. I am using Borland Pascal 7.0 under MS-Dos 5.0.π>Basically, the Program I am writing will be run under Novell Netwareπ>3.11. What I need to do is determine the User's full user name. Iπ>could do this using Novell Interrupts, but they are impossible to figureπ>out (At least For me). So what I wanted to do, was use Novell'sπ>"WHOAMI" command. What this does is return the user's full name andππWell, I think you'll find it harder to to a Dos exec and parse the output afterπreading it from a File than asking Netware what it is. Plus you must depend onπthe user having access to use the command. I'm on some Novell networks whereπthat command File is not present because it wasn't considered important.πHere's how to get the user name from Netware...π}πProgram UserID;ππUsesπ Dos, Strings;ππTypeπ RequestBuf = Recordπ RequestLen : Word; { Number of Bytes in the rest of the Record }π SubFunction : Byte; { Function from Novell we are requesting }π ConnectionNum : Byte; { Connection number that is making the call }π end;ππ ReplyBuf = Recordπ ReplyLength : Word; { Number of Bytes in the rest of the Record }π ObjectId : LongInt; { Novell refers to everything by Objects like users}π ObjectType : Word;π ObjectName : Array[1..48] of Char;π LoginTime : Array[1..7] of Char;π end;ππVarπ I:Word;π ReqBuf : RequestBuf;π RepBuf : ReplyBuf;π Regs : Registers;π UserName : String[48];ππbeginπ Regs.AH := $DC;π MsDos(Regs); { Get the connection number }ππ ReqBuf.RequestLen := 2; { User ID request, must give connection }π ReqBuf.SubFunction := $16; { number }π ReqBuf.ConnectionNum := Regs.AL;ππ RepBuf.ReplyLength := 61; { Return buffer For name }ππ Regs.AH := $E3; { Call Novell For user name }π Regs.DS := Seg(ReqBuf); { Passing it the request buffer indicating }π Regs.SI := Ofs(ReqBuf); { the data we want and a reply buffer to send }π Regs.ES := Seg(RepBuf); { us back the information }π Regs.DI := Ofs(RepBuf);π MsDos(Regs);ππ { Object name now contians the users ID, use the StringS Unit Functions }π { to print the null-terminated String }π WriteLn(StrPas(@RepBuf.ObjectName));πend.ππ{πThat will read in a Novell User ID For you.π}π 4 05-28-9313:52ALL SWAG SUPPORT TEAM GET-ID3.PAS IMPORT 22 {π[ Does anyone know the syntax For Novell-specific interrupts in Pascalπ[(or C)? I have posted this message in all the pascal confs nad haven'tπ[had any replies. Any help is appreciated.π[ Specifically, I need to use interrupts to find the username, securityπ[in a certain directory and groups belongs to.ππSince this is Novell-specific I hope the moderator won't mind if Iπanswer this one in this conference, rather than Pascal conf...ππYou Absolutely NEED a copy of "System Calls - Dos" from Novell. Thisπbook has every last call you'll ever need For getting inFormation out ofπNetWare. Warning: some of their inFormation is erroneous, and you'llπjust have to do things like count up the size of the Reply buffers, Forπexample, and not trust their reported Record sizes.ππJust as an example of how to use the inFormation from the System Callsπbook, here's an example of a Function I slapped together to return aπ3-Character username. Pretty much all the Novell calls work the sameπway: you set up a Request buffer and a Reply buffer, then you read yourπresults into whatever Format you want them. Hope this helps:π}ππFunction GetNetUserID:String;πVarπ NovRegs:Registers;π Answer:String[3];π iii:Integer;π ConnectNo:Byte;π Request : Recordπ Len : Word; {LO-HI}π SubF : Byte;π ConnNum: Word; {HI-LO}π end;π Reply : Recordπ Len : Word; {LO-HI}π ObjID : LongInt; {HI-LO}π ObjType: Word;π ObjName: Array[1..48] of Byte;π LogTime: Array[1..7] of Byte;π end;πbeginπ if (ReqdNetType <> Novell) thenπ GetNetUserID := copy(ParamStr(2),1,3);π if (ReqdNetType = Novell) thenππ beginππ With NovRegs doπ beginπ AH := $dc;π AL := $00;π cx := $0000;π end;ππ MsDos(NovRegs);π ConnectNo:=NovRegs.AL;ππ For iii := 1 to 48 doπ beginπ Reply.ObjName[iii] := $00;π end;ππ With Request doπ beginπ Len := Sizeof(Request) - 2;π SubF := $16;π ConnNum:= (ConnectNo);π end;ππ Reply.Len := Sizeof(Reply) - 2;ππ With NovRegs doπ beginπ AH := $e3;π DS := Seg(Request);π SI := ofs(Request);π ES := Seg(Reply);π DI := ofs(Reply);π end;ππ MsDos(NovRegs);π Answer:=' ';ππ For iii:= 1 to 3 doπ beginπ Answer[iii]:= chr(Reply.ObjName[iii]);π end;ππ GetNetUserID:= Answer;π end;πend; {GetNetUserID}ππ{πThat $e3 in the AH register is the generic bindery call. $16 is theπsubFunction For "Get Connection Name" in the Bindery calls.π}π 5 05-28-9313:52ALL SWAG SUPPORT TEAM ISFILOPN.PAS IMPORT 4 Varπ Fi : File;ππFunction ISOpen(Var Fil:File):Boolean;π(* Returns True is File has is open ON A NETWORK!!! *)πVarπ P:^Byte;πbeginπ P:=@Fil;π If P^=0 then IsOpen:=False else IsOpen:=True;πend;ππbeginπ Assign(Fi,'FileOPEN.PAS');π Writeln(ISOpen(Fi));πend. 6 05-28-9313:52ALL SWAG SUPPORT TEAM LOCKREC.PAS IMPORT 15 {πThe following Program is a slight modification of one posted by ZachπLinnet. The problem is it doesn't lock the use of the File and allowsπmultiple PC's to access the File at the same time. Also, it seems toπtake input from the keyboard when it isn't supposed to and I am unableπto locate why. How could I improve this to actually lock the File?πWhat if I just wanted to lock one or two Records?π}ππProgram Sample_File_Locking_Program;πUsesπ Crt;πTypeπ Fi = File of Integer;πVarπ FileName : String;π f : Fi;π x, n : Integer;π Choice : Char;ππbeginπ {$I-}π FileName := 'e:\test\test.dat';π Assign(f,FileName);π Repeatπ Write('Option [rwq] ? '); choice := ReadKey;π Writeln(choice);π Case choice ofπ 'r' : beginπ Writeln('Attempting to read : ');π Reset(f);π While Ioresult <> 0 doπ beginπ Writeln('Busy waiting...');π Reset(f);π end;π Write('Reading now...');π For x := 1 to 1000 doπ Read(f,n);π Writeln('done!');π Close(f);π end;π 'w' : beginπ Writeln('Attempting to Write : ');π Reset(f);π if Ioresult = 2 thenπ ReWrite(f);π While Ioresult <> 0 doπ beginπ Writeln('Busy waiting...');π Reset(f);π end;π Write('Writing now...');π For x := 1 to 1000 doπ Write(f,x);π Writeln('done!');π Close(f);π end;π end; { Case }π Until Choice = 'q';π {$I+}πend.π 7 08-17-9308:47ALL SWAG SUPPORT TEAM NETINFO Unit IMPORT 60 ,î PROGRAM NetInfo;πUSES Crt, Dos;πCONSTπ Redirector = $08;π Receiver = $80;π Messenger = $04;π Server = $40;π AnyType = $CC;ππTYPEπ String15 = STRING[15];π LocalDevice = ARRAY[1..16] OF Char;π RedirDevice = ARRAY[1..128] OF Char;π DevicePtr = ^DevInfo;π DevInfo = RECORDπ LD : LocalDevice;π RD : RedirDevice;π ND : DevicePtrπ END;ππVAR Done:Boolean;π Name:String15;π Ver:Word;π I,Key:Integer;π DevIn:STRING[16];π RedIn:STRING[128];π LDevice:LocalDevice;π RDevice:RedirDevice;π DeviceList,NextDevice : DevicePtr;ππPROCEDURE ClrCursor;πVAR Regs : Registers;πBEGINπ Regs.CH:=$20;π Regs.AH:=$01;π INTR($10,Regs);πEND;ππPROCEDURE SetCursor;πVAR Regs : Registers;πBEGINπ Regs.AH:=1;π IF LastMode <> Mono THENπ BEGINπ Regs.CH:=6;π Regs.CL:=7π ENDπ ELSEπ BEGINπ Regs.CH:=12;π Regs.CL:=13π END;π INTR($10,Regs);πEND;ππFUNCTION GetExtended : Integer;πVAR CH:Char;πBEGINπ CH:=#0;GetExtended:=0;CH:=ReadKey;π IF Ord(CH)=0 THENπ BEGINπ CH:=ReadKey;π GetExtended:=Ord(CH)π ENDπEND;ππFUNCTION GetFileName(S:STRING):STRING;πVAR FileName:STRING[11];π I:Integer;πBEGINπ FileName:='';π I:=1;π WHILE S[I]<>#0 DOπ BEGINπ FileName[I]:=(S[I]);π I:=I+1π END;π FileName[0]:=Chr(i-1);π GetFileName:=FileNameπEND;ππFUNCTION ChkNetInterface : Boolean;πVAR NetRegs:Registers;πBEGINπ NetRegs.AH:=$00;π INTR($2A,NetRegs);π IF NetRegs.AH = 0 THEN ChkNetInterface:=FALSEπEND;ππPROCEDURE ChkPCLan;πVAR NetRegs:Registers;π ChkType:Integer;πBEGINπ NetRegs.AX:=$B800;π INTR($2F,NetRegs);π IF NetRegs.AH = 0 THENπ WriteLn('Network Not Installed')π ELSEπ BEGINπ ChkType:= NetRegs.BL AND AnyType;π IF (ChkType AND Server > 0) THENπ WriteLn('Server')π ELSEπ IF (ChkType AND Messenger > 0) THENπ WriteLn('Messenger')π ELSEπ IF (ChkType AND Receiver > 0) THENπ WriteLn('Receiver')π ELSEπ IF (ChkType AND Redirector > 0) THENπ WriteLn('Redirector')π ELSEπ WriteLn('Unknown Type')π ENDπEND;ππFUNCTION NetName : String15;πVAR NetRegs:Registers;π Name:ARRAY[1..15] OF Char;ππBEGINπ WITH NetRegs DOπ BEGINπ AH:=$5E;π AL:=$00;π DS:=Seg(Name);π DX:=Ofs(Name)π END;π MsDos(NetRegs);π IF NetRegs.CH<>0 THENπ NetName:=Nameπ ELSEπ NetName:='NOT DEFINED'πEND;ππFUNCTION ChkDrive(DriveNo:Integer):Integer;πVAR DriveRegs: Registers;πBEGINπ WITH DriveRegs DOπ BEGINπ AH:=$44;π AL:=$09;π BL:=DriveNo;π MsDos(DriveRegs);π IF (FLAGS AND 1) = 0 THENπ IF (DX AND $1000) = $1000 THENπ ChkDrive := 1π ELSEπ ChkDrive := 0π ELSEπ ChkDrive := AX * -1π ENDπEND;ππFUNCTION GetDevices: DevicePtr;πVAR NetRegs: Registers;π FstDevice, CurDevice,NewDevice : DevicePtr;π DevName: LocalDevice;π RedName: RedirDevice;π NextDev: Integer;π More : Boolean;ππBEGINπMore:=TRUE;πFstDevice:=NIL;πCurDevice:=NIL;πNextDev:=0;πWHILE More DOπBEGINπ WITH NetRegs DOπ BEGINπ AH:=$5F;π AL:=$02;π BX:=NextDev;π DS:=Seg(DevName);π SI:=Ofs(DevName);π ES:=Seg(RedName);π DI:=Ofs(RedName)π END;π MsDos(NetRegs);π IF (NetRegs.FLAGS AND 1) = 1 THENπ More:=FALSEπ ELSEπ BEGINπ NEW(NewDevice);π NewDevice^.LD:=DevName;π NewDevice^.RD:=RedName;π NewDevice^.ND:=NIL;π IF (CurDevice = NIL) AND (FstDevice=NIL) THENπ BEGINπ CurDevice:=NewDevice;π FstDevice:=NewDeviceπ ENDπ ELSEπ BEGINπ CurDevice^.ND:=NewDevice;π CurDevice:=NewDeviceπ END;π Inc(NextDev)π ENDπEND;πGetDevices:=FstDeviceπEND;ππPROCEDURE AssignDevice(DevName:LocalDevice;π RedName:RedirDevice);πVAR NetRegs: Registers;π DevType: Byte;π Dummy : Integer;ππBEGINπIF Pos(':',DevName)=2 THENπ DevType:=4π ELSEπ DevType:=3;ππ WITH NetRegs DOπ BEGINπ AH:=$5F;π AL:=$03;π BL:=DevType;π CX:=0;π DS:=Seg(DevName);π SI:=Ofs(DevName);π ES:=Seg(RedName);π DI:=Ofs(RedName)π END;π MsDos(NetRegs);π IF (NetRegs.FLAGS AND 1) = 1 THENπ BEGINπ TextColor(Red);GotoXY(WhereX+6,WhereY);π WriteLn('An Error Occurred on Assign');π TextColor(Red+128);GotoXY(WhereX+13,WhereY);π Write('Press Any Key');π Dummy:=GetExtended;π TextColor(White);π ClrScrπ ENDπEND;ππPROCEDURE DeleteDevice(DevName:LocalDevice);πVAR NetRegs: Registers;π Dummy : Integer;ππBEGINπ WITH NetRegs DOπ BEGINπ AH:=$5F;π AL:=$04;π DS:=Seg(DevName);π SI:=Ofs(DevName)π END;π MsDos(NetRegs);π IF (NetRegs.FLAGS AND 1) = 1 THENπ BEGINπ TextColor(Red);GotoXY(WhereX+6,WhereY);π WriteLn('An Error Occurred on Delete');π TextColor(Red+128);GotoXY(WhereX+13,WhereY);π Write('Press Any Key');π Dummy:=GetExtended;π TextColor(White);π ClrScrπ ENDπEND;ππFUNCTION SrchDevice(Drive:LocalDevice):DevicePtr;πVAR NDevice:DevicePtr;πBEGINπ NDevice:=GetDevices;π WHILE (NDevice <> NIL) ANDπ (Copy(NDevice^.LD,1,3) <>π Copy(Drive,1,3)) DOπ BEGINπ NDevice:=NDevice^.NDπ END;πSrchDevice:=NDeviceπEND;ππPROCEDURE DisplayDrives;πVAR I:Integer;π LDevice:LocalDevice;π NextDevice : DevicePtr;πBEGINπ FOR I:=1 TO 26 DOπ BEGINπ CASE ChkDrive(I) OFπ 0 : BEGINπ Write(#32,#32,Chr(64+I),':');π GotoXY(WhereX+3,WhereY);π WriteLn('Local')π END;π 1 : BEGINπ Write(#32,#32,Chr(64+I),':');π GotoXY(WhereX+3,WhereY);π Write('Remote');π LDevice[1]:=Chr(64+I);π LDevice[2]:=':';π LDevice[3]:=#0;π NextDevice:=SrchDevice(LDevice);π GotoXY(WhereX+7,WhereY);π WITH NextDevice^ DOπ WriteLn(Copy(RD,1,Pos(#0,RD)))π ENDπ ENDπ ENDπEND;ππPROCEDURE ScrnSetup;πBEGINπ ClrCursor;π TextBackground(Blue);π TextColor(White);π ClrScr;π GotoXY(30,2);Write('Network Status');π TextColor(LightGray);π GotoXY(2,5);Write('Dos Version:');π GotoXY(21,5);Write('Network Name:');π GotoXY(51,5);Write('Node Type:');π TextColor(White);π GotoXY(31,7);Write('Drive Status');π TextColor(LightGray);π GotoXY(20,9);Write('Drive');π GotoXY(27,9);Write('Location');π GotoXY(40,9);Write('Connection');π GotoXY(15,25);Write('F1 - Assign Device');π GotoXY(35,25);Write('F2 - Delete Device');π GotoXY(55,25);Write('F10 - Exit');π TextBackground(Black);π Ver:=DosVersion;π GotoXY(15,5);π WriteLn(Lo(Ver),'.',Hi(Ver))πEND;ππPROCEDURE SetScreen(W,X,Y,Z,Back,Txt:Integer);πBEGINπ Window(W,X,Y,Z);π TextColor(Txt);π TextBackground(Back);π ClrScrπEND;ππBEGINπ ScrnSetup;π IF ChkNetInterface THENπ BEGINπ GotoXY(35,5); WriteLn(NetName);GotoXY(62,5);π ChkPCLan;π Window(20,10,60,20);ClrScr;π DisplayDrives;π REPEATπ SetScreen(20,21,60,24,Blue,White);π Key:=GetExtended;π CASE Key OFπ 59:BEGINπ SetCursor;π Write('Drive to Redirect ');π ReadLn(DevIn);π Write('Remote Definition ');π ReadLn(RedIn);π ClrCursor;π FOR I:= 1 TO Ord(DevIn[0]) DOπ LDevice[I]:=DevIn[I];π LDevice[Ord(DevIn[0])+1]:=#0;π FOR I:= 1 TO Ord(RedIn[0]) DOπ RDevice[I]:=RedIn[I];π RDevice[Ord(RedIn[0])+1]:=#0;π AssignDevice(LDevice,RDevice)π END;π 60:BEGINπ Write('Drive to Delete ');π SetCursor;π ReadLn(DevIn);π ClrCursor;π FOR I:= 1 TO Ord(DevIn[0]) DOπ LDevice[I]:=DevIn[I];π LDevice[Ord(DevIn[0])+1]:=#0;π DeleteDevice(LDevice)π ENDπ END;π SetScreen(20,10,60,20,Black,LightGray);π DisplayDrives;π UNTIL Key = 68;ππ ENDπ ELSEπ WriteLn('NetBIOS Interface Not Available')πEND.ππ 8 08-27-9321:42ALL JEFF SHANNON Novell File Locking IMPORT 14 ,î {πJEFF SHANNONππNovell/File Locking/Sharingππ> Does anyone have any samples of network File sharing/access code For Turboπ> Pascal/Borland Pascal 6-7.ππThis is from the Advanced Turbo Pascal Techniques book by Chris Ohlsen andπGary Stroker. It's For TP 5.5 but I'm sure you could make use of it.ππOops, I hope I didn't violate any copyright laws by posting this code. Iπdoubt the authors of the book would sue me as it is a FINE book and Iπrecommend it to all. Now the publishers are a different story...π}ππUnit FileLock;ππInterfaceππUsesπ Dos;ππFunction Lock(Var UnTyped; pos, size : LongInt) : Boolean;πFunction UnLock(Var UnTyped; pos, size : LongInt) : Boolean;ππImplementationππFunction Lock(Var UnTyped; pos, size : LongInt) : Boolean;πVarπ reg : Registers;π f : File Absolute UnTyped;ππbeginπ pos := pos * FileRec(f).RecSize;π size := size * FileRec(f).RecSize;π reg.AH := $5C;π reg.AL := $00;π reg.BX := FileRec(f).Handle;π reg.CX := Hi(pos);π reg.DX := Lo(pos);π reg.SI := Hi(size);π reg.DI := lo(size);π Intr($21, reg);π if ((reg.Flags and FCarry) <> 0) thenπ Lock := Falseπ elseπ Lock := True;πend;ππFunction UnLock(Var UnTyped; pos, size : LongInt) : Boolean;πVarπ reg : Registers;π f : File Absolute UnTyped;πbeginπ pos := pos * FileRec(f).RecSize;π size := size * FileRec(f).RecSize;π reg.AH := $5C;π reg.AL := $01;π reg.BX := FileRec (f).Handle;π reg.CX := Hi(pos);π reg.DX := Lo(pos);π reg.SI := Hi(size);π reg.DI := Lo(size);π Intr($21, reg);π if ((reg.Flags and FCarry) <> 0) thenπ Unlock := Falseπ elseπ Unlock := True;πend;ππend.π 9 08-27-9321:42ALL ROBERT KOHLBUS Netware Bindary Object IMPORT 39 ,î {πRobert C. Kohlbusππ I'm trying to compile and run a program that I wrote, with BP70π'real' mode, in 'Protected Mode'. This program uses Interrupt 21hπfunctions B80Xh and E3h, the Novell Netware ones. The program worked fineπin 'real' mode, but gives incorrect information in 'Protected Mode'. Afterπcalling Borland, they said it was because the DPMI overlay file didn't knowπhow to handle the interrupts I was trying to access. They suggested that Iπlook at a file from their BBS called READWRTE.PAS that shows how to handleπinterrupts in a 'Protected Mode' program. Basically this example file, justπinterrupt 31h (Simulate Real Mode Interrupt). My problem is that my programπcontinues to hang up, even after following their example. Below is a sampleπpart of my program. If anyone can lend a hand, I would be in their debt.π}ππProgram Getid; { Get unique Id for Novell Netware Bindery Object }ππusesπ Dos, Crt, WinApi;ππtypeπ TDPMIRegs = recordπ edi, esi, ebp, reserved, ebx, edx, ecx, eax: LongInt;π flags, es, ds, fs, gs, ip, cs, sp, ss : Word;π end;ππvarπ Hexid : string;π R: TDPMIRegs;ππ RequestBuffer : recordπ PacketLength : integer;π functionval : byte;π ObjectType : packed array [1..2] of byte;π NameLength : byte;π ObjectName : packed array [1..47] of char;π end;ππ ReplyBuffer : recordπ ReturnLength : integer;π UniqueID1 : packed array [1..2] of byte;π UniqueID2 : packed array [1..2] of byte;π ObjectType : packed array [1..2] of byte;π ObjectName : packed array [1..48] of byte;π end;πππfunction DPMIRealInt(IntNo, CopyWords: Word; var R: TDPMIRegs): Boolean; assembler;πasmπ mov ax, 0300hπ mov bx, IntNoπ mov cx, CopyWordsπ les di, Rπ int 31hπ jc @errorπ mov ax, 1π jmp @doneπ@error:π xor ax, axπ @Done:πend;ππfunction LongFromBytes(HighByte, LowByte: Byte): LongInt; assembler;πasmπ mov dx, 0π mov ah, HighByteπ mov al, LowByteπend;ππfunction LongFromWord(LoWord: Word): LongInt; assembler;πasmπ mov dx, 0π mov ax, LoWord;πend;ππfunction RealToProt(P: Pointer; Size: Word; var Sel: Word): Pointer;πbeginπ SetSelectorBase(Sel, LongInt(HiWord(LongInt(P))) Shl 4 + LoWord(LongInt(P)));π SetSelectorLimit(Sel, Size);π RealToProt := Ptr(Sel, 0);πend;πππprocedure GetObjectID(Name : string; ObjType : Word);πconstπ HEXDIGITS : Array [0..15] of char = '0123456789ABCDEF';ππvar Reg : Registers;π i : integer;π Hex_ID, S : string;π ErrorCode : word;π ObjectId : array[1..8] of byte;πππbeginπ with RequestBuffer doπ beginπ PacketLength := 52;π FunctionVal := $35;π ObjectType[1] := $0;π ObjectType[2] := ObjType;π NameLength := length(Name);π for i := 1 to length(Name) doπ ObjectName[i] := Name[i];π end;π ReplyBuffer.ReturnLength := 55;ππ { Original Code that worked in Real Mode }π{π Reg.ah := $E3;π Reg.ds := seg(RequestBuffer);π Reg.si := ofs(RequestBuffer);π Reg.es := seg(ReplyBuffer);π Reg.di := ofs(ReplyBuffer);ππ MsDos(Reg);π}ππ { New Code From Borland Example }π FillChar(R, SizeOf(TDPMIRegs), #0);π R.Eax := $E3;π R.ds := seg(RequestBuffer);π R.Esi := LongFromWord(ord(RequestBuffer));π R.es := seg(ReplyBuffer);π R.Edi := LongFromWord(ord(ReplyBuffer));π DPMIRealInt($21, 0, R);ππ{π S := 'None';π Errorcode := Reg.al;π if Errorcode = $96 then S := 'Server out of memory';π if Errorcode = $EF then S := 'Invalid name';π if Errorcode = $F0 then S := 'Wildcard not allowed';π if Errorcode = $FC then S := 'No such object *'+QueueName+'*';π if Errorcode = $FE then S := 'Server bindery locked';π if Errorcode = $FF then S := 'Bindery failure';π S := 'Error : '+ S;π Writeln(S);π}π Hex_ID := '';ππ Hex_ID := hexdigits[ReplyBuffer.UniqueID1[1] shr 4];π Hex_ID := Hex_ID + hexdigits[ReplyBuffer.UniqueID1[1] and $0F];π Hex_ID := Hex_ID + hexdigits[ReplyBuffer.UniqueID1[2] shr 4];π Hex_ID := Hex_ID + hexdigits[ReplyBuffer.UniqueID1[2] and $0F];π Hex_ID := Hex_ID + hexdigits[ReplyBuffer.UniqueID2[1] shr 4];π Hex_ID := Hex_ID + hexdigits[ReplyBuffer.UniqueID2[1] and $0F];π Hex_ID := Hex_ID + hexdigits[ReplyBuffer.UniqueID2[2] shr 4];π Hex_ID := Hex_ID + hexdigits[ReplyBuffer.UniqueID2[2] and $0F];π while Hex_ID[1] = '0' doπ Hex_ID := copy(Hex_ID,2,length(Hex_ID));ππ Hexid := Hex_ID;ππend;ππbeginπ Hexid := '';π ClrScr;ππ { Get An Objects Idπ Parameters (2) Object Name, Object Typeπ Object Name = String[8];π Object Type = Word;π 1 Userπ 2 User Groupπ 3 Print Queueπ 4 File Serverπ 5 Job Serverπ 6 Gatewayπ 7 Print Serverπ }π GetObjectID('BUSINESS', 3); { Get Print Queue's ID }π Writeln('Hexid for BUSINESS is ',hexid);ππend.π 10 08-27-9321:49ALL KERRY SOKALSKY Network "Real" name IMPORT 19 ,î {π-> I don't have an answer to your question, but would you happen to knowπ-> how to return a user's full name (as stored in syscon)? Thanks.ππI assume you already have the user's login name. Here is a procedureπthat will get a user's full name. If you are going to do a lot ofπNetware programming I suggest you get "Programmers Guide to Netware" byπCharles Rose. ISBN # 0-07-607029-8. It documents all of the Netwareπfunctions and also talks about IPX/SPX programming.π}ππUsesπ Dos;ππVarπ Regs : Registers;ππFunction Full_Name(User_Name : String) : String;πTypeπ RequestBuffer = Recordπ RequestBufferLength : Word;π Code : Byte;π ObjectType : Word;π ObjectNameLength : Byte;π ObjectName : Array[1..48] of char;π SegmentNumber : Byte;π PropertyNameLength : Byte;π PropertyName : Array[1..15] of char;π end;ππ ReplyBuffer = Recordπ ReplyBufferLength : Word;π PropertyValue : Array[1..128] of char;π MoreSegments : Byte;π PropertyFlags : Byte;π end;ππVarπ Request : RequestBuffer;π Reply : ReplyBuffer;π PropertyName : String[15];π Counter : Byte;π Temp : String[128];ππbeginπ PropertyName := 'IDENTIFICATION';π Request.RequestBufferLength := SizeOf(Request) - 2;π Request.Code := $3D;π Request.SegmentNumber := 1;π Request.ObjectType := $0100;π Request.ObjectNameLength := SizeOf(Request.ObjectName);π FillChar(Request.ObjectName, SizeOf(Request.ObjectName), #0);ππ For Counter := 1 to length(User_Name) doπ Request.ObjectName[Counter] := User_Name[Counter];ππ Request.PropertyNameLength := SizeOf(Request.PropertyName);π FillChar(Request.PropertyName, SizeOf(Request.PropertyName), #0);ππ For Counter := 1 to Length(PropertyName) doπ Request.PropertyName[Counter] := PropertyName[Counter];ππ Regs.AH := $E3;π Regs.DS := Seg(Request);π Regs.SI := Ofs(Request);ππ Reply.ReplyBufferLength := SizeOf(Reply) - 2;π Regs.ES := Seg(Reply);π Regs.DI := Ofs(Reply);ππ MSDos(Regs);ππ Temp := '';π Counter := 1;π While (Reply.PropertyValue[Counter] <> #0) doπ beginπ Temp := Temp + Reply.PropertyValue[Counter];π inc(Counter);π end;π Full_Name := Temp;πend;ππbeginπ Writeln(Full_Name('SOKALSKY'));πend. 11 11-21-9309:50ALL JIM ROBB WHOBE For NETWARE SWAG9311 28 ,î {πFrom: JIM ROBBπSubj: Re: Netware "User name"ππ I need a way to get the current user name from the netware shell.π For instance, if I'm logged into server MYSERVER as user SUPERVISOR,π I need some way to get 'supervisor' as the user name...ππThis should do the job. The two calls are "Get Connection Number" (DCh) andπ"Get Connection Information" (E3h 16h), both from the Connection Services API.πThe calls work with Advanced Netware 1.0 and all later versions. Code testedπon 3.11 NetWare.ππBeware the weak error-checking - the program doesn't check the version ofπNetware, or even that the user is logged onto the network.π}ππprogram WhoBeMe;ππuses Dos;πππprocedure GetUserName( var UserName : string );ππvarπ Request : record { Request buffer for "Get Conn Info" }π Len : Word; { Buffer length - 2 }π Func : Byte; { Subfunction number ( = $16 ) }π Conn : Byte { Connection number to be researched }π end;ππ Reply : record { Reply buffer for "Get Conn Info" }π Len : Word; { Buffer length - 2 }π ID : Longint; { Object ID (hi-lo order) }π Obj : Word; { Object type (hi-lo order again) }π Name : array[ 1..48 ] of Byte; { Object name as ASCII string }π Time : array[ 1.. 7 ] of Byte; { Y, M, D, Hr, Min, Sec, DOW }π { Y < 80 is in the next century }π { DOW = 0 -> 6, Sunday -> Saturday }π Filler : Byte { Call screws up without this! }π end;ππ Regs : Registers;π W : Word;ππbeginπ Regs.AX := $DC00; { "Get Connection Number" }π MsDos( Regs );π { "Get Connection Information" }ππ with Request do { Initialize request buffer: }π beginπ Len := 2; { Buffer length, }π Func := $16; { API function, }π Conn := Regs.AL { Returned in previous call! }π end;ππ Reply.Len := SizeOf( Reply ) - 2; { Initialize reply buffer length }ππ with Regs doπ beginπ AH := $E3; { Connection Services API call }π DS := Seg( Request ); { Location of request buffer }π SI := Ofs( Request );π ES := Seg( Reply ); { Location of reply buffer }π DI := Ofs( Reply );π MsDos( Regs )π end;ππ if ( Regs.AL = 0 ) { Success code returned in AL }π and ( Hi( Reply.Obj ) = 1 ) { Obj of 1 is a user, }π and ( Lo( Reply.Obj ) = 0 ) then { stored Hi-Lo }π with Reply doπ beginπ Move( Name, UserName[ 1 ], 48 ); { Convert ASCIIZ to string }π UserName[ 0 ] := #48;π W := 1;π while ( UserName[ W ] <> #0 )π and ( W < 48 ) doπ Inc( W );π UserName[ 0 ] := Char( W - 1 )π endπ elseπ UserName := ''πend;ππvarπ TheName : string;ππbeginπ GetUserName( TheName );π WriteLn( 'I be ', TheName )πend.π 12 11-21-9309:43ALL NORBERT IGL NETWARE User name SWAG9311 15 ,î {πFrom: NORBERT IGLπSubj: Netware "User name"ππ I need a way to get the current user name from the netware shell.π For instance, if I'm logged into server MYSERVER as user SUPERVISOR,π I need some way to get 'supervisor' as the user name. (Kind of likeπ WHOAMI would return: You are user SUPERVISOR on server MYSERVER)π}ππuses dos;ππfunction lStationNumber:byte; { MY logical Station(connection)-Number }πvar regs : Registers;πbeginπ regs.ah := $DC;π MsDos(regs );π lStationNumber := pcregs.al;πend;ππfunction GetUserName( Station: byte):String;πVarπ i : byte;π Regs : Registers;π name : string[50];π Reply : Recordπ Filler1 : Array [1..8] of byte;π ObjectName : Array [1..48] of Byte;π Filler2me : Array [1..8] of Byte;π End;π Request : Recordπ PacketLen : Integer;π vFunc : Byte;π ConnNb : Byte;π End;ππBeginπ With Request doπ beginπ PacketLen := 2;π vFunc := 22;π ConnNbm := Station;π End;π Reply.ReturnLength := 62;π With Regs Do Beginπ Ah := $e3;π Ds := Seg(Request);π Si := Ofs(Request);π Es := Seg(Reply);π Di := Ofs(Reply);π End;π MsDos(Reg);π { 1 2 3 4 }π {123456789012345678901234567890123456789012345678}π name := ' ';π If Regs.al = 0 Then with reply doπ beginπ move( objectName[1] , name[1], 48 );π i := pos(#0, name );π name[0] := char(i-1);π end;πend;ππ[...]ππvar me : byte;ππbeginπ me := lStationNumber;π writeln(' Hello, ', GetUserName( me ),π ' you''re hooked in on Station # ', me );πend.π 13 01-27-9412:10ALL DENNIS RUSH Novell Detection SWAG9402 32 ,î {π> Is there a way to detect if a system is running under Novellπ> Netware? There must be an interrupt to do that, but wich one?πππ Yes there is. Although this is in assembly, I'm sure you can digπout what you need and convert it to Pascal or inline ASM. I've alsoπincluded for the more common multitaskers. I always try to check forπeach at the beginning of a program so I can code to take advantage ofπthe features of whatever system it's operating under, or at leastπprevent problems.π}ππ;*****************************************************************π;* Check to see if we are running under a Novell Network *π;*****************************************************************π.public chk_novellπ.proc chk_novell autoπ .push es,di ; Protect the registers well useπ xor ax,ax ; and clear themπ push axπ push axπ .pop es,diπ mov ax,07A00H ; Novel Netware installation checkπ int 2FH ; Check itπ or al,al ; If installed, al = 0FFHπ ; ES:DI ptr -> far entry point forπ ; routines otherwise accessed throughπ ; INT 21Hπ jnz double_check ; Appears to be installed, see if thereπ ; is a far address in ES:DIπ stc ; Set carry to indicate no networkπ .pop es,di ; restore what we usedπ ret ; and exitπdouble_check:π push di ; Checkπ pop axπ or ax,ax ; Is it emptyπ jnz in_novell ; No has pointer so were in a networkπ push esπ pop axπ or ax,ax ; Is it emptyπ jnz in_novell ; No has pointerπ stc ; No pointer to far address so no networkπ ; Chance of a ptr to 0000:0000 areπ ; basically non-existantπin_novell:π .pop es,di ; Clean up after ourselvesπ ret ; and go homeπ.endp chk_novellπ;***********************************************************************π;* Check to see if we are running under Desqview, TopView, or TaskView *π;***********************************************************************π.public chk_desqπ.proc chk_desq autoπ .push ax,bx ; Save registers we will useπ mov ax,1022H ; This is the get version functionπ ; that TopView installs for Int 15H.π ; Most TopView compatibles use theπ ; same function so we can check forπ ; several with just one callπ xor dx,dx ; Clear dxπ int 15H ; Make the callπ cmp bx,0a01H ; DesqView 2.x returns 0A01Hπ jnz try_task ; Did we get itπ mov @dataseg:Desqview,1 ; YES, save it and go homeπ jmp short No_Viewπtry_task: ; No, Try TaskViewπ cmp bx,0001H ; TaskView Returns 0001Hπ jnz try_top ; Get itπ mov @dataseg:TaskView,1 ; Yesπ jmp short No_Viewπtry_top: ; No, try TopView. Top View returns it'sπ or bx,bx ; version so just test for non-zeroπ jz No_View ; is it non-zeroπ mov @dataseg:TopView,1 ; Yes, save itπNo_View:π .pop ax,bx ; Restore regs and go homeπ retπ.endp chk_desqππ{π Hope this helps. BTW, I don't know about the later versions ofπWindows, but the older versions respected the Desqview installationπcheck.π}π 14 01-27-9412:16ALL JIM ROBB Novell User Name 2 SWAG9402 27 ,î {π> I need a way to get the current user name from the netware shell.π> For instance, if I'm logged into server MYSERVER as user SUPERVISOR,π> I need some way to get 'supervisor' as the user name...ππThis should do the job. The two calls are "Get Connection Number" (DCh) andπ"Get Connection Information" (E3h 16h), both from the Connection Services API.πThe calls work with Advanced Netware 1.0 and all later versions. Code testedπon 3.11 NetWare.ππBeware the weak error-checking - the program doesn't check the version ofπNetware, or even that the user is logged onto the network.π}ππprogram WhoBeMe;ππuses Dos;πππprocedure GetUserName( var UserName : string );ππvarπ Request : record { Request buffer for "Get Conn Info" }π Len : Word; { Buffer length - 2 }π Func : Byte; { Subfunction number ( = $16 ) }π Conn : Byte { Connection number to be researched }π end;ππ Reply : record { Reply buffer for "Get Conn Info" }π Len : Word; { Buffer length - 2 }π ID : Longint; { Object ID (hi-lo order) }π Obj : Word; { Object type (hi-lo order again) }π Name : array[ 1..48 ] of Byte; { Object name as ASCII string }π Time : array[ 1.. 7 ] of Byte; { Y, M, D, Hr, Min, Sec, DOW }π { Y < 80 is in the next century }π { DOW = 0 -> 6, Sunday -> Saturday }π Filler : Byte { Call screws up without this! }π end;ππ Regs : Registers;π W : Word;ππbeginπ Regs.AX := $DC00; { "Get Connection Number" }π MsDos( Regs );π { "Get Connection Information" }ππ with Request do { Initialize request buffer: }π beginπ Len := 2; { Buffer length, }π Func := $16; { API function, }π Conn := Regs.AL { Returned in previous call! }π end;ππ Reply.Len := SizeOf( Reply ) - 2; { Initialize reply buffer length }ππ with Regs doπ beginπ AH := $E3; { Connection Services API call }π DS := Seg( Request ); { Location of request buffer }π SI := Ofs( Request );π ES := Seg( Reply ); { Location of reply buffer }π DI := Ofs( Reply );π MsDos( Regs )π end;ππ if ( Regs.AL = 0 ) { Success code returned in AL }π and ( Hi( Reply.Obj ) = 1 ) { Obj of 1 is a user, }π and ( Lo( Reply.Obj ) = 0 ) then { stored Hi-Lo }π with Reply doπ beginπ Move( Name, UserName[ 1 ], 48 ); { Convert ASCIIZ to string }π UserName[ 0 ] := #48;π W := 1;π while ( UserName[ W ] <> #0 )π and ( W < 48 ) doπ Inc( W );π UserName[ 0 ] := Char( W - 1 )π endπ elseπ UserName := ''πend;ππvarπ TheName : string;ππbeginπ GetUserName( TheName );π WriteLn( 'I be ', TheName )πend.π 15 01-27-9412:16ALL GLENN CROUCH Novell User Name 3 SWAG9402 25 ,î {π>I need a way to get the current user name from the netware shell.π>For instance, if I'm logged into server MYSERVER as user SUPERVISOR,π>I need some way to get 'supervisor' as the user name. (Kind of likeπ>WHOAMI would return: You are user SUPERVISOR on server MYSERVER)ππIn our library of routines we've developed (and continue to do so) lots ofπroutines for Novell Netware. The following routines (developed by Peter Ogdenπis to and myself) are to get the current user and I hope I've removed all ourπinter-library references so that it's of use to you:π}ππtypeπ String48 = string [48];ππconstπ NetError : Integer = 0;ππfunction GetConnNo : Byte; assembler;ππasmπ MOV AX, $DC00π INT $21πend;ππprocedure GetConnInfo (ConnectionNum : Byte; var ObjType : Word;π var ObjName : String48);ππvarπ ReqBuf : recordπ Size : Word;π FixedValue : Byte;π ConnNumber : Byte;π end;ππ ReplyBuf : recordπ Size : Word;π ID : LongInt;π ObType : Word;π Name : array [1..48] of Byte;π Reserved : Byte;π LoginTime : array [1..7] of Byte;π end;ππ Regs : Registers;π Counter : Integer;π NameString : String;ππbeginπ with ReqBuf doπ beginπ Size := SizeOf (ReqBuf) - 2;π FixedValue := $16;π ConnNumber := ConnectionNum;π end;ππ ReplyBuf.Size := SizeOf (ReplyBuf) - 2;π with Regs doπ beginπ AH := $E3;π DS := Seg (ReqBuf);π SI := Ofs (ReqBuf);π ES := Seg (ReplyBuf);π DI := Ofs (ReplyBuf);π MsDos (Regs);ππ NetError := AL;π if NetError <> 0 thenπ beginπ ObjType := 0;π ObjName := '';π endπ elseπ with ReplyBuf doπ if ID <> 0 thenπ beginπ Counter := 1;π NameString := '';π while (Name[Counter] <> 0) doπ beginπ NameString := NameString + Chr (Name [Counter]);π Inc (Counter);π end;π ObjName := NameString;π ObjType := Swap (ObType);π endπ elseπ beginπ ObType := 0;π ObjName := '';π end;π end;πend;ππfunction GetUserID : String48;ππvarπ CN : Byte;π UserName : String48;π ObjType : Word;ππbeginπ CN := GetConnNo;π GetConnInfo (CN, ObjType, UserName);π GetUserID := UserName;πend;πππI use this with Novell Netware 386 v3.11, as that is the Network that most ofπour Commercial Applications have been developed for. I know speed ups areπpossible especially in processing the ASCIIZ, but hey we only call this routineπonce in an application so it's not high on our priorities for optimisation.ππ 16 01-27-9412:16ALL JIM ROBB Novell Name SWAG9402 29 ,î {π>To anyone that can help me, this is my problem: I want to program a simpleπ>E-Mail program for Novel Network v2.1. But i have one problem. While inπ>a pascal programmed program, how do i find out the user login nameπ>automatically?ππI tested this code on Novell 3.11, but the API calls should also work on yourπ2.1 network. The login time is also available as a by-product.π}ππprogram ShowUser;ππuses Dos;ππtypeπ NovTime = recordπ LoginYear : byte; { 0 to 99; if < 80, year is in 21st century }π LoginMonth : byte; { 1 to 12 }π LoginDay : byte; { 1 to 31 }π LoginHour : byte; { 0 to 23 }π LoginMin : byte; { 0 to 59 }π LoginSec : byte; { 0 to 59 }π LoginDOW : byte; { 0 to 6, 0 = Sunday, 1 = Monday ... }π end;πππ{ GetConnInfo --------------------------------------------------------------}π{ ----------- }ππfunction GetConnInfo( Connection : Byte;π var ConnName : string;π var ConnTime : NovTime ) : Byte;πVARπ NameArray : array[ 0..48 ] of Byte absolute ConnName;π NovRegs : Registers;ππ Request : recordπ Len : Word;π Func : Byte;π Conn : Byteπ end;ππ Reply : recordπ Len : Word;π ID : Longint;π Obj : Word; { Object type }π Name : array[ 1..48 ] of Byte;π Time : NovTime;π Filler : Byte { Isn't in my Novell docs, but won't work without! }π end;πππbeginπ with Request do { Initialize request buffer: }π beginπ Len := 2; { Buffer length, }π Func := $16; { API function, }π Conn := Connection { Connection # to query }π end;ππ Reply.Len := SizeOf( Reply ) - 2; { Initialize reply buffer length }ππ with NovRegs doπ beginπ AH := $E3; { Connection Services API call }π DS := Seg( Request ); { Location of request buffer }π SI := Ofs( Request );π ES := Seg( Reply ); { Location of reply buffer }π DI := Ofs( Reply );π MsDos( NovRegs ); { Make the call }π GetConnInfo := AL { Completion code is function result }π end;ππ with Reply doπ beginπ Obj := Swap( Obj ); { If object is a user and }π if ( Obj = 1 ) and ( NovRegs.AL = 0 ) then { call was successful, }π beginπ ConnTime := Time; { Return login time }π Move( Name, NameArray[ 1 ], 48 ); { Convert ASCIIZ to string }π NameArray[ 0 ] := 1;π while ( NameArray[ NameArray[ 0 ] ] <> 0 )π and ( NameArray[ 0 ] < 48 ) doπ Inc( NameArray[ 0 ] );π Dec( NameArray[ 0 ] )π endπ endπend;πππ{ GetConnNo ----------------------------------------------------------------}π{ --------- }ππfunction GetConnNo : byte;ππvarπ NovRegs : Registers;ππbeginπ NovRegs.AH := $DC;π MsDos( NovRegs );π GetConnNo := NovRegs.ALπend;πππ{ MAIN =====================================================================}π{ ==== }ππvarπ UserName : string;π LoginTime : NovTime;ππbeginπ GetConnInfo( GetConnNo, UserName, LoginTime );π WriteLn( 'User''s name is ', UserName )πend.π 17 01-27-9412:23ALL PER-ERIC LARSSON Using Novell? SWAG9402 5 ,î {π> Is there a way to detect if a system is running under Novell Netware?π> There must be an interrupt to do that, but wich one?π}ππUsesπ Dos;ππFunction stationno : byte;πvarπ B : byte;π Regs : Registers;πbeginπ With Regs doπ beginπ ah := $DC;π ds := 0;π si := 0;π end;π MsDos( Regs ); {INT $21,ah=dh}π b := Regs.al;π stationno := b;πend;ππ{ Should return 0 if not attached to a novell server otherwiseπ workstation number }ππbeginπ Writeln(StationNo);πend.π 18 02-15-9407:51ALL SWAG SUPPORT TEAM Misc NOVELL API Calls SWAG9402 29 ,î Program Novell_API_Examples;ππ{ Misc. Novell Advanced Netware 2.1+ API examples to retrieve info on theπ user who is running this programπ}ππUSES DOS, CRT;ππCONSTπ HexDigit: array [0..15] of char = '0123456789ABCDEF';π Days_Of_Week : Array[0..6] of string = ('Sunday','Monday','Tuesday',π 'Wednesday','Thursday','Friday',π 'Saturday');πππTYPEπ string2 = STRING[2];π string4 = STRING[4];πππVARπ Reg : DOS.Registers;π RCode : Integer;π Connect : Byte;π Address : String;πππfunction HexByte(B: byte): string2;π beginπ HexByte := HexDigit[B shr 4] + HexDigit[B and $F];π end;πππfunction Hex(I: integer): string4;π beginπ Hex := HexByte(hi(I)) + HexByte(lo(I));π end;πππFunction Get_Connection_Number : Integer;π { |π | Returns the connection number for the current sessionπ |π }π beginπ Reg.AH := $DC;π intr($21,Reg);π Get_Connection_Number := Reg.AL;π end;πππFunction Get_Station_Address(var Address: String): Integer;π { |π | Returns the Physical Station Address (NIC Number)π |π }π varπ S1, S2, S3 : String;π beginπ Reg.AH := $EE;π intr($21,Reg);π Address := Hex(Reg.CX) + Hex(Reg.BX) + Hex(Reg.AX);π Get_Station_Address := $00;π end;πππFunction Get_Login_Name : String;π { |π | Who's calling?π |π }π varπ Reg : DOS.REGISTERS;π Loop,π Connection : Byte;π TmpStr : String;π Request_Buf : Recordπ BufLen : Integer;π SubFunc : Byte;π Connection : Byte;π end;π Reply_Buf : Recordπ BufLen : Integer;π Obj_ID : LongInt;π Obj_Type : Integer;π Obj_Name : Array[1..48] of char;π Login_Time : Recordπ Year : Byte;π Month : Byte;π Day : Byte;π Hour : Byte;π Minute : Byte;π Second : Byte;π Day_No : Byte;π end;π end;ππ beginπ TmpStr := '';π RCode := 0;π Connect := Get_Connection_Number;π fillchar(Request_Buf,sizeof(Request_Buf),0);π fillchar(Reply_Buf,sizeof(Reply_Buf),0);ππ Request_Buf.SubFunc := $16;π Request_Buf.Connection := Connect;π Request_Buf.BufLen := sizeof(Request_Buf);π Reply_Buf.BufLen := sizeof(Reply_Buf);π Reg.AH := $E3;π Reg.DS := seg(Request_Buf);π Reg.SI := ofs(Request_Buf);π Reg.ES := seg(Reply_Buf);π Reg.DI := ofs(Reply_Buf);π intr($21,Reg);π Loop := 1;π while ((Reply_Buf.Obj_Name[Loop] <> #0) and (Loop <= 48)) doπ beginπ TmpStr := TmpStr + Reply_Buf.Obj_Name[Loop];π inc(loop);π end;π Get_Login_Name := TmpStr;π end;πππProcedure Pause;π varπ ch : char;π beginπ writeln;π write('Press Any Key To Continue ');π ch := readkey;π writeln;π end;πππBEGINπ clrscr;π writeln('Get Novell Station Info - (C) Rick Ryan, 1989');π writeln;π Connect := Get_Connection_Number;π Writeln(' Connection ID: ', Connect);ππ RCode := Get_Station_Address(Address);π writeln('Station Address: ',Address,' With ErrCode of ', RCode);ππ writeln('Login Name = ',Get_Login_Name);ππ Pause;ππEND. 19 02-18-9406:59ALL NORBERT IGL Novell Detection SWAG9402 9 ,î π{π MB> First - How can I detect if Novell netware is running on aπ MB> computer? and if you can tell me that... how can I get theπ MB> current version? }ππuses dos ;πvar Regs : registers ;π ReplyBuffer : array[1..40] of char ;πππfunction IPX_Loaded:boolean;πbeginπ Regs.AX := $7A00 ;π intr($2F,Regs) ;π IPX_Loaded := (Regs.AL = $FF)πend;ππfunction Netbios_Loaded:Boolean;πbeginπ Regs.AH := $35; (* DOS function that checks an interrupt vector *)π Regs.AL := $5C; (* Interrupt vector to be checked *)π NetBios_Installed := True;π msdos(Regs) ;π if ((Regs.ES = 0) or (Regs.ES = $F000))π then NetBios_Installed := Falseπend;πππfunction NetShell_Installed:Boolean;πbeginπ with Regs do beginπ AH := $EA ;π AL := 1 ;π BX := 0 ;π ES := seg(ReplyBuffer) ;π DI := ofs(ReplyBuffer) ;π end ; (* with do begin *)π msdos(regs) ;π NetShell_Installed := (Regs.BX = 0)πend.ππ