Page 1 of 3

Server configuration 'Home' path

Posted: Tue Mar 08, 2016 1:38 pm
by Robert
I have a Client / Server configuration; The Target field on my desktop icon is "D:\BlackBoxServer.exe /Use D:\BlackBox".

I want to find a file, but I only know the file's Relative path; eg "\Tools\Docu\MyModule.odc"

So I want to try adding the two Home prefixes "D:\BlackBox" & then "D:\BlackBoxServer". Note that these strings are examples; I don't actually know what they are.

I can find the first string by "home := Files.dir.This ('')(HostFiles.Locator).path$".
How can I find the Server's home path?


Thanks

Re: Server configuration 'Home' path

Posted: Wed Mar 09, 2016 3:12 am
by Ivan Denisov
You can make HostFiles.startupDir readble and recompile BlackBox.exe . This will allow easily access to server path.

Re: Server configuration 'Home' path

Posted: Wed Mar 09, 2016 3:28 am
by Ivan Denisov
The second option you can parse WinApi.GetCommandLineW()

Re: Server configuration 'Home' path

Posted: Wed Mar 09, 2016 10:28 am
by Robert
Ivan Denisov wrote:You can make HostFiles.startupDir readble and recompile BlackBox.exe . This will allow easily access to server path.
Thanks for this and the next suggestion.
This is simple, but I can't use it unless read exporting startupDir became part of the standard BlackBox distribution.

What I have done is repeat the code that generates startupDir, ie lines 2 & 3 of HostFiles.Init.

This involves calling WinApi.GetModuleFileNameW. This function leads to slightly easier parsing than GetCommandLineW.

Re: Server configuration 'Home' path

Posted: Wed Nov 02, 2016 3:07 am
by DGDanforth
Here is what I do

Code: Select all

	PROCEDURE Strip (VAR path: Name); (*Remove "\BlackBox.exe" from path*)
	VAR n: INTEGER;
	BEGIN
		n := LEN(path$)-1;
		WHILE (0 < n) & (path[n] # "/") & (path[n] # "\") DO DEC(n) END;
		path[n] := 0X
	END Strip;
	
	PROCEDURE GetStartup (VAR startup: String);
	VAR res: INTEGER; path: Name;
	BEGIN
		res := WinApi.GetModuleFileNameW(0, path, LEN(path));
		Strip(path);
		startup := Strings.New(path)
	END GetStartup;
	
-Doug

Re: Server configuration 'Home' path

Posted: Thu Nov 17, 2016 5:16 pm
by a-mcintosh
Robert wrote:
Ivan Denisov wrote:You can make HostFiles.startupDir readble and recompile BlackBox.exe . This will allow easily access to server path.
Thanks for this and the next suggestion.
This is simple, but I can't use it unless read exporting startupDir became part of the standard BlackBox distribution.

What I have done is repeat the code that generates startupDir, ie lines 2 & 3 of HostFiles.Init.

This involves calling WinApi.GetModuleFileNameW. This function leads to slightly easier parsing than GetCommandLineW.
I consider this to be a bug in HostFiles.Old. Specifically, HostFiles.Old always returns loc.path = <Server Path> even when a file is opened that only exists on the Client directory.

The patch to HostFiles.Old below fixes this bug. Perhaps this can be brought into the distribution so that Robert can use it.

This fix
  • Repairs the broken behavior.
  • Does not disturb the HostFiles interface.
  • Allows the client program to be portable, i.e., not use underlying system calls.
  • Feels distasteful because it makes a deep change to a field in a non VAR pointer parameter.

Code: Select all

	PROCEDURE (d: Directory) Old (loc: Files.Locator; name: Files.Name; shrd: BOOLEAN): Files.File;
		VAR res, i, j: INTEGER; f: File; ref: WinApi.HANDLE; fname: FullName; type: Files.Type; s: BYTE;
			shadow : FullName; (*alm 2016-11-13*)
	BEGIN
		ASSERT(loc # NIL, 20); ASSERT(name # "", 21);
		res := ok; f := NIL;
		WITH loc: Locator DO
			Append(loc.path, name, "", loc.maxLen, fname);
			f := ThisFile(fname);
			IF f # NIL THEN
				IF ~shrd OR (f.state = exclusive) THEN loc.res := Error(sharingErr); RETURN NIL
				ELSE loc.res := ok; loc.path := f.loc.path$; (*alm 2016-11-13*) RETURN f
				END
			END;
			IF shrd THEN s := shared ELSE s := exclusive END;
			OpenFile(s, fname, ref, res);
			IF ((res = fileNotFoundErr) OR (res = pathNotFoundErr)) & (loc.rootLen > 0) THEN
				GetShadowDir(loc, fname);
				shadow := fname$; (*alm 2016-11-13*)
				Append(fname, name, "", loc.maxLen, fname);
				f := ThisFile(fname);
				IF f # NIL THEN
					IF ~shrd OR (f.state = exclusive) THEN loc.res := Error(sharingErr); RETURN NIL
					ELSE loc.res := ok; loc.path := f.loc.path$; (*alm 2016-11-13*); RETURN f
					END
				END;
				OpenFile(s, fname, ref, res);
				IF res = ok THEN loc.path := shadow$ END (*alm 2016-11-13*)
			END;
			IF res = ok THEN
				NEW(f); f.loc := loc;
				f.swapper := -1; i := 0;
				GetType(name, type);
				f.InitType(type);
				ASSERT(ref # invalid, 107);
				f.ref := ref; f.name := fname$; f.state := s; f.t := Kernel.Time();
				f.len := WinApi.GetFileSize(ref, j)
			END
		END;
		loc.res := Error(res);
		RETURN f
	END Old;

Here is a client program that captures the bug, and which shows correct behavior when HostFiles is patched and MyBlackBox is relinked.

Code: Select all

(*2016-11-13 alm
	I wanted to programmatically access the server / shadow directory name.  I thought that information should be returned by HostFiles.Old.  It turns out that the working directory path is always returned.  I propose that the actual path of the file should be available in the loc(HostFiles).path variable after return from the call.
	
	This program shows that behavior.  It does it twice because there is an execution path that is unique for a shared previously existing file.  Notice that this program gives an incorrect path for the Loc1 / Name1, but correct for Loc0 / Name0.
	
*)
MODULE AlmShowPath;
	IMPORT
		Files, HostFiles, StdLog;
		
	CONST  (*Compile and execute this program twice, with scenario 0 and scenario 1.*)
		Loc0 = "Std/Mod"; Name0 = "Api.odc";  (*works*)
		Loc1 = "Alm/Mod"; Name1 = "Path.odc";  (*fails*)

	PROCEDURE ShowAbsoluteFileName*;
		VAR
			loc : Files.Locator;
			f1, f2 : Files.File;
	BEGIN
		loc := Files.dir.This( Loc0 );
		f1 := Files.dir.Old( loc, Name0, TRUE );
		IF f1=NIL THEN StdLog.String( "file not opened: " ) ELSE StdLog.String( "file opened: ") END;
		StdLog.String( loc(HostFiles.Locator).path$ + "/" + Name0 );
		StdLog.Ln;
		
		loc := Files.dir.This( Loc0 );
		f2 := Files.dir.Old( loc, Name0, TRUE );
		IF f2=NIL THEN StdLog.String( "file not opened: " ) ELSE StdLog.String( "file opened: ") END;
		StdLog.String( loc(HostFiles.Locator).path$ + "/" + Name0 );
		StdLog.Ln
	END ShowAbsoluteFileName;
	
END AlmShowPath.

 AlmShowPath.ShowAbsoluteFileName

Re: Server configuration 'Home' path

Posted: Thu Nov 17, 2016 9:16 pm
by Robert
Sorry (its a bit late at night) but I am rather confused by this post.

You say "Old always returns loc.path = <Server Path>" & "the working directory path is always returned".
My first post (which could be wrong, I haven't checked it) says loc.path is the Client home path.

Can you clarify if "shadow directory" refers to the Client or Server?
Can you clarify if "working directory" refers to the Client or Server?

I haven't studied your suggestion in detail, but it seems that you are proposing that loc.path is sometimes the Client, and sometimes the Server. That seems to be potentially confusing.

And I think that your suggestion requires one to open a file just to discover the home path, which I would have thought was unnecessary.

Re: Server configuration 'Home' path

Posted: Fri Nov 18, 2016 2:24 am
by a.mcintosh
I went and read your original post more closely, and I wonder, does the top level of your drive D: contain some directories with the names Docu, System, Host, Dev? That is, do D:\Docu, D:\System, D:\Host, D:\Dev exist?

Alternately, can you set things up so that BlackBoxServer.exe is in the directory D:\BlackBox, and that directory contains those (and other) subdirectories?

I might have directories such as
D:\project\blackbox <--- server or startup directory. Contains BlackBox.exe and all the subdirectories from the distribution. Probably is read only.
D:\project\MySplendedSoftware <--- client or user or work directory. The target of the /USE parameter.

Re: Server configuration 'Home' path

Posted: Fri Nov 18, 2016 5:32 am
by luowy
a.mcintosh wrote:I might have directories such as
D:\project\blackbox <--- server or startup directory. Contains BlackBox.exe and all the subdirectories from the distribution. Probably is read only.
D:\project\MySplendedSoftware <--- client or user or work directory. The target of the /USE parameter.
after your patch, the server's files(Modules) will not be readonly when you modified them(opened with "Source" of popup menu) at client side.

Re: Server configuration 'Home' path

Posted: Fri Nov 18, 2016 7:49 pm
by a.mcintosh
luowy wrote:after your patch, the server's files(Modules) will not be readonly when you modified them(opened with "Source" of popup menu) at client side.
Thanks for looking at this. I learned something new.

First, I ran my modified system with client and server directories. I opened the repository and selected HostCmds at random and opened it with the Source popup menu. The Dev menu said that it was in "Edit" mode. The File menu had "Save" disabled. I typed a few blanks into the file and executed ctl-S and it saved the file to the server directory. This seems to confirm your report.

Second, I also downloaded the install file from http://blackboxframework.org/index.php?cID=home,en-us and installed it into blackbox-canonical and created a new directory blackbox-empty. Running on Ubuntu under Wine, I invoked it with a server/client setup, I opened the system repository and repeated the 1st scenario actions. The result is the same.

Previously, I used the Mod link to open source files. When I did this, the Dev drop down menu was in browse mode, not edit mode.

So, I don't think that my modification introduced this behavior.

Again, thank you, and please keep looking for trouble.

Code: Select all

env WINEPREFIX="/home/amcintosh/.wine" wine C:\\users\\amcintosh\\project\\bb7-rc1\\blackbox-canonical\\BlackBox.exe  /USE C:\\users\\amcintosh\\project\\bb7-rc1\\blackbox-empty &