Subject: Problems rewriting mount.c for mingw32 (egcs/gcc)
From: [email-masked] (Bartlee A. Anderson)

22 Mar 1998 13:42:54 -0800
Message-ID: <[email-masked]>
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="------------1693413D3F18"
To: [email-masked]
Cc: [email-masked], [email-masked], [email-masked],
        [email-masked]

This is a multi-part message in MIME format.

--------------1693413D3F18
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Enclosed is mount.c
This kind of works, but I'm unclear as to how the enumeration fails.
You see the same strings for different entries. It may be due to the
silent mounts, but I can't imagine.
Is it a coding problem (is something more complex needed/or is it
brain-dead)? What are the silent mounts for?
What does mount --reset really do? Looks like it finds the drives
that are there and adds them as text with /<drive letter> and
adds the /dev/xxx with silent mounts. Anything else?
-- 
Bartlee A. Anderson     System Test (Interfaces-Tools-Automation-ISDN)
Rockwell International                    Electronic Commerce Division
300 Bauman Ct.                                [email-masked]
MS 933-605      Opinions my own, not Rockwell's   VOICE (630) 227-8975
Wood Dale, IL 60191                               FAX   (630) 227-9771

--------------1693413D3F18
Content-Type: text/plain; charset=us-ascii; name="mount.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="mount.c"

#include <windows.h>
//#define MYDEBUG

// Here we can define a mount type for switching between various mount types
// I have chosen CYGNUS_b18 as a starting point. We can choose b19 or
// an entirely new location. May want to follow CYGNUS for now, but
// we don't have to.

#define REG_CYGNUS_b18
//#define REG_CYGNUS_B19 you b19 guys can enter this one
#ifdef REG_CYGNUS_b18
#define REG_ROOT HKEY_CURRENT_USER
#endif

char * mount_parentkey()
{
	// returning non-static local strings is a problem
	static char key[256];
#ifdef REG_CYGNUS_b18
	sprintf(key,"Software\\Cygnus Solutions\\CYGWIN.DLL setup\\b15.0\\mounts");
#endif
	return(key);
}

char * mount_subkey(int mount)
{
	// returning non-static local strings is a problem
	static char subkey[256];
	sprintf(subkey,"%s\\%02X", mount_parentkey(), mount);
	return(subkey);
}

HKEY
NewMountKey(int mount) // creates/opens a subkey by mount
{
static HKEY hKeyRes;
DWORD dwDisp;
LONG lRes;
char * whichkey;
char * subkey = mount_subkey(mount);
char * parentkey = mount_parentkey();

	if(mount == -1)
	{
		whichkey = parentkey;
	}
	else
	{
		whichkey = subkey;
	}

	lRes = RegCreateKeyEx( REG_ROOT, whichkey,
		0, "", REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
		&hKeyRes, &dwDisp);

	if(lRes != ERROR_SUCCESS)
	{
		printf("Can't open key REG_ROOT\\%s",subkey);
		exit(1);
	}
	else
	{
		return(hKeyRes);
	}
}

LONG
NewMountValStr(HKEY hKey, char * name, char * val)
{
	LONG lRes;

	lRes = RegSetValueEx( hKey, name, 0, REG_SZ, val, lstrlen(val));
	return(lRes);
}

LONG
NewMountValNum(HKEY hKey, char * name, DWORD * val)
{
	LONG lRes;

	lRes = RegSetValueEx( hKey, name, 0, REG_DWORD, (char *)val, (DWORD)sizeof(val));
	return(lRes);
}

LONG
del_mount(int mount)
{
	HKEY hKeyRes = 0;
	LONG lRes;
	char * subkey = mount_subkey(mount);

	lRes = RegOpenKeyEx( REG_ROOT, subkey,
		0, KEY_ALL_ACCESS, &hKeyRes);
	if(lRes != ERROR_SUCCESS)
	{
#ifdef MYDEBUG
		printf("failed to open subkey %s\n",subkey);
#endif
		return(lRes);
	}

	lRes = RegDeleteKey( REG_ROOT, subkey);
	if(lRes != ERROR_SUCCESS)
	{
#ifdef MYDEBUG
		printf("failed to delete subkey %s\n",subkey);
#endif
	}

	return(lRes);
}

int
add_mount(int mount, char * dos_fname, char * unix_fname,
		DWORD bf, DWORD mf, DWORD sf)
{
	HKEY hKey;
        LONG lRes;
	char procid[100];
	hKey = NewMountKey(mount);

	lRes = NewMountValStr(hKey ,"native", dos_fname);
	if(lRes != ERROR_SUCCESS)
		return(1);
	lRes = NewMountValStr(hKey ,"unix", unix_fname);
	if(lRes != ERROR_SUCCESS)
		return(1);
	lRes = NewMountValNum(hKey ,"fbinary", &bf);
	if(lRes != ERROR_SUCCESS)
		return(1);
	lRes = NewMountValNum(hKey ,"fmixed", &mf);
	if(lRes != ERROR_SUCCESS)
		return(1);
	lRes = NewMountValNum(hKey ,"fsilent", &sf);
	if(lRes != ERROR_SUCCESS)
		return(1);

	RegCloseKey( hKey );
	return(0);
}

char *
get_mount_value_data(int mount, char * valname, DWORD dwtype)
{
	HKEY hKey;
	// valname from above
	// reserved set to 0
	// dwtype passed in
	DWORD dwbytes;
	static char szbuf[261];
	LPTSTR lpszbuf;
	LONG lres;
	dwbytes = 256; // won't work unless this is set to something ... 
			// probably because addr of 0 is NULL? or not...

	//lpszbuf = &szbuf[lstrlen(szbuf)]; with this, we get strings
	//catenated for subsequent calls - don't know how or why
	lpszbuf = (LPSTR) &szbuf; // this works ... ;)
	hKey=NewMountKey(mount);

	lres = RegQueryValueEx(hKey, valname, 0, &dwtype, lpszbuf, &dwbytes);

	RegCloseKey( hKey );

	if(lres == ERROR_SUCCESS)
	{
#ifdef MYDEBUG
		switch(dwtype)
		{
			case REG_DWORD :
				printf("[%d]",(DWORD) * szbuf);
			break;
			case REG_SZ :
				printf("%s",szbuf);
			break;
		}
#endif
		return(szbuf);
	}
	else return((char *)NULL);

}

void
showmounts()
{	
	HKEY hKey;
	char name[1001];
	DWORD dwName = 1000;
	LPSTR lpszName = (LPSTR) name;
	char div1[80], div2[80];
	int len1, len2, i;
	LONG lRes;
	DWORD dwSubkey = 0; // has to be 0
	char pdos[300], punix[300];
	DWORD dwbin, dwmix, dwsil;
	printf("Device           Directory           Type        Flags\n");
	do
	{
// format 17 20 12
//d:               /d                  native      no-mixed,text=binary
		hKey = NewMountKey(-1);
		lRes = RegEnumKeyEx(hKey,dwSubkey,lpszName,&dwName,
			NULL, NULL, NULL, NULL);
		RegCloseKey( hKey );

	   if(lRes != ERROR_NO_MORE_ITEMS)
	   {
		dwSubkey++;
		strcpy(pdos, get_mount_value_data(atoi(lpszName), \
						"native", REG_SZ));

		strcpy(punix, get_mount_value_data(atoi(lpszName), \
						"unix", REG_SZ));

		dwbin = *get_mount_value_data(atoi(lpszName), \
						"fbinary", REG_DWORD);

		dwmix = *get_mount_value_data(atoi(lpszName), \
						"fmixed", REG_DWORD);

		dwsil = *get_mount_value_data(atoi(lpszName), \
						"fsilent", REG_DWORD);
		len1 = 17 - strlen(pdos) ;
		len2 = 20 - strlen(punix) ;
		for(i=0;i<len1;i++)
		{
			div1[i]=' ';
		}
		div1[i]='\0';
		for(i=0;i<len2;i++)
		{
			div2[i]=' ';
		}
		div2[i]='\0';

		printf("%s%s%s%snative      %smixed,text%s=binary subkey[%d]\n",
				pdos,div1,punix,div2,
					dwmix==0?"no-":"",
					dwbin==0?"!":"",dwSubkey);
		if(lRes != ERROR_SUCCESS)
			if(lRes != ERROR_MORE_DATA)
				printf("error is [%d]\n",lRes);
	   }
	}
	while(lRes != ERROR_NO_MORE_ITEMS);
}

int
is_dos_mount(char * dos_path)
{	
	HKEY hKey;
	char name[1001];
	DWORD dwName = 1000;
	LPSTR lpszName = (LPSTR) name;
	LONG lRes;
	DWORD dwSubkey = 0; // has to be 0
	char *pnative;
	int ret_flag = FALSE;
	do
	{
		hKey = NewMountKey(-1);
		lRes = RegEnumKeyEx(hKey,dwSubkey,lpszName,&dwName,
			NULL, NULL, NULL, NULL);
		RegCloseKey( hKey );
		dwSubkey++;
		pnative = get_mount_value_data(atoi(lpszName), \
						"native", REG_SZ);
		if(strcmp(pnative,dos_path)==0)
		{
#ifdef MYDEBUG
			printf("match %S to %s\n", pnative, dos_path);
#endif
			ret_flag = TRUE;
		}
	}
	while(lRes != ERROR_NO_MORE_ITEMS);
	return (ret_flag);
}

void usage()
{
	printf("Usage mount [-m] [-b] <dospath> <unixpath>\n");
	printf("-m = add mixed case support [currently not recommended]\n");
	printf("-b = text files are equivalent to binary files (newline = \\n)\n");
	printf("To reset the mount table use: mount --reset (unsupported)\n");
	exit(0);

}

main(int argc, char **argv)
{
	char dpath[270];
	char upath[270];
	int mixed_flag, binary_flag, reset_flag, silent_flag;
	mixed_flag = binary_flag = reset_flag = silent_flag = 0;

	// should probably investigate how initial silent flags are set
	// maybe part of reset which is not implemented

	if(argc == 1)		// show the mounts for no parameters passed
	{
		showmounts();
		exit(0);
	}
	else if((argc >= 3)||(argc <= 5))
	{
		while(argc--)
		{
		   argv++;
		   switch(**argv)
		   {
			case '-':
			{
			  switch(*(*argv+1))
			  {
				case 'b':
				{
					binary_flag = 1;
				}
				break;

				case 'm':
				{
					mixed_flag = 1;
				}
				break;

				case '-':
				if(strcmp((*argv+2),"reset") == 0)
				{
					reset_flag = 1;
				}
				break;

				default:
					usage();
				break;
			  }
			}
			break;
			default:
			if (argc == 2) // need 2 filenames yet
			{
				argc --;
				strcpy(dpath,*argv++);
				printf("dos_path %s",dpath);
				
				argc --;
				strcpy(upath,*argv++);
				printf("unix_path %s\n",upath);
			}
			else
			{
				usage();
			}
			break;
		   }
		}
	}
// there is no validation of the dos or unix paths, you should know what you
// want	
// There is however protection from mounting the same unix path twice
// which would leave an ambiguous possibility
	if(!is_dos_mount(dpath))
	{
		add_mount(0xdd, dpath, upath, binary_flag ,mixed_flag, silent_flag);
	}
	printf("mount failed: Device or resource busy\n");
}

--------------1693413D3F18--

-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".