Creating directories on Vista machines using .NET

G

Guest

Hi guys,

I've noticed that simple .NET code to create directories does not seem to
work on Vista.

Take the following simple example (implemented in a Windows forms
application):

==========================

FileInfo executableFile = new FileInfo(Application.ExecutablePath);
DirectoryInfo directory = executableFile.Directory.CreateSubdirectory("Test");

if (!directory.Exists)
{
directory.Create();
}

==========================

This works fine on XP, but not on Vista, despite the “belt and bracesâ€
approach!

I guess this is to do with the improved security model in Vista. Clearly
there will be no way to override this in code (else it is useless in
preventing hackers from playing), but it would be good to find some kind of
solution to this problem, even if that was popping up a box for the user to
confirm that they’re happy for Vista to perform the action.

Does anyone have any ideas as to how I can proceed?

Thanks in advance,

Steve.
 
P

Patrice

Even in XP, AFAIK you can't create a directory in "program files" (is this
where your executable is ?) under a non administrative account. Depending on
what you are trying to store, I would rather try another location...

Else what is the error you get ?
 
G

Guest

Hi Patrice,

Thanks for your reply!

I didn't realise that you don't intrinsically get create permissions on
Program File folders if you're not an administrator. Just goes to show that
almost all users run Windows under an administrator account all the time. No
wonder viruses are so prevalent!

Under Vista, when you try to create folders under the Program Files, you
don’t get an error. The application continues as though everything is fine,
except the folder is not created. This is the case even when you’re logged in
as an administrator. However, you can get round this by "running the program
as an administrator". To do this, you must find the executable you are trying
to run (because the option isn’t available from the shortcut), and right
click. The option is something like “Run as administrator…†In that case, the
application is able to create the folder. If you're already logged on as an
administrator, the thing just works. Otherwise, a dialog appears for you to
enter administrator login information.

XP is a different matter. When you log in as an administrator, the folder is
created with no problems. However, when you log in as a standard user, you
get a nasty .NET unhandled exception when you try to create the folder.

Has anyone got any suggestions as to how I can make my application more
elegant? I am aware of Permission classes in .NET; in this case, the one I
need is FileIOPermission. However, I’m not exactly sure what this can do or
what the best way to use them would be. Surely, the Assert() method won’t
actually give the application the permissions it needs?!

Thanks in advance,

Steve.
 
P

Peter Duniho

[...]
Has anyone got any suggestions as to how I can make my application more
elegant? I am aware of Permission classes in .NET; in this case, the one
I
need is FileIOPermission. However, I’m not exactly sure what this can do
or
what the best way to use them would be. Surely, the Assert() method won’t
actually give the application the permissions it needs?!

Well, setup/installation programs do what you want, so it must be
possible. :)

I haven't used Vista much yet. However, I did read something about it
having "virtualization" features for the registry and filesystem for
applications that want access to protected areas. So when your
application tries to create a directory under Program Files and fails
silently, it may be that this virtualization is actually allowing it to
succeed but the directory that is created is not in the real Program Files
directory.

If this is the case, then that application should have an actual "Test"
directory that it can use, under Program Files, but you wouldn't see that
directory on the disk version of Program Files. Where it actually is, I
don't know...I don't recall reading anything about the actual
implementation of the virtualization stuff.

If you want to create a directory that is actually under Program Files,
there is probably some sort of security token thing you can get to allow
that, even without explicitly running as administrator. When that
happens, a UAC dialog should still come up (if UAC is enabled), and then
the "Test" directory should be able to be created in the actual Program
Files directory.

Note that the above is basically a bunch of hand-waving. I've never
actually done that, so I don't have any of the specifics that would be
useful in figuring it out. :) But hopefully it gives you some direction
for looking into it yourself.

Pete
 
A

Alun Harford

Steve said:
Hi Patrice,

Thanks for your reply!

I didn't realise that you don't intrinsically get create permissions on
Program File folders if you're not an administrator.

So when a trusted program checks its directory for plugins, you can't
have another program able to create files in there if it's not trusted.
It would be a massive security hole.
Under Vista, when you try to create folders under the Program Files, you
don’t get an error. The application continues as though everything is fine,
except the folder is not created.

The directory is created in
X:\Users\username\AppData\Local\VirtualStore\Program Files\YourApp

When you read the files in Program Files\YourApp the system will first
check the VirtualStore for you.

Of cause, Microsoft has been saying for almost a decade that you
shouldn't write your programs assuming you have access to Program Files
unless you know you're running as an administrator, but some developers
still don't get it.
"Just goes to show that almost all users run Windows under an
administrator account all the time. No wonder viruses are so prevalent!"

Alun Harford
 
P

Patrice

So IMO your best it NOT to write at this location (typically most home
users are running as administrators and so do I but at work I'm
running under a non administrative account as all developers
should ;-))

Also make sure you don't hardcode the path but use the SpecialFolders
constants. Vista and XP doesn't have physically the same location for
folders. See http://msdn2.microsoft.com/en-us/library/system.environment.specialfolder(VS.71).aspx
and CommonApplicationData lloks like your best bet.

Still weird it fails silently (or it could redirect you to some other
location making the directory not found when you browse the disk ?).
 
J

Jeffrey Tan[MSFT]

Hi Patrice,

Thanks for your feedback.

Yes, just as other community members pointed out, your code runs without
error because of the virtualization feature of Vista User Account
Control(UAC). That is, any write operation to the Program Files directory
is redirected to per-user local profile directory. If you are using Windows
Explorer to find the file, you will see a "Compatibility Files" button in
the toolbar. If you click this button, it will help you to navigate to the
redirected folder.

The best practise is using Environment.SpecialFolder.ApplicationData to
find the per-user application data folder path and save the data there.
Please see my original thread below for more information:
http://www.thescripts.com/forum/thread638856.html

Finally, if you are interested to understand the Vista new UAC security
enhancement, I highly recommend "Mark Russinovich"'s online video below, it
is almost the best tech talk on UAC topic(level 400):
"Windows Vista User Account Control Internals"
http://www.microsoft.com/emea/itsshowtime/sessionh.aspx?videoid=360

Hope it helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
G

Guest

Hi guys,

Thanks for your first class assistance everyone!

It feels a little like I’ve opened a can of worms here, and from my point of
view, I’m not sure how to proceed.

The reason for my original question is that I’ve written a .NET application
that installs to the Program Files directory. The application interacts with
Access databases installed into folders below the folder where the .NET
executable is installed. These databases are used to store essential
application settings; these settings are extremely dynamic in nature. I use
the System.Data.OleDb namespace to interact with these databases. My
installer has been created using the installer project in Visual Studio.

If I install the application to the program files folder on an XP machine,
under a non-administrative account, I get all sorts of problems, the first of
which being an MDAC error. This is the case even if I run the install using
administrator rights, having logged on as a normal user.

There are literally loads of applications out there that run without problem
under a normal user account, and still manage to create folders under their
main folder. This is the case with most modern games. However, I have
realised that the default install location for most games is to put them at
C:\ level, completely ignoring the Program Files directory. It would seem
that games manufacturers have come to the conclusion that the only way to be
sure their applications can do all they need to without getting security
problems is to forget about the program files folder altogether.

I have made a version of my application that also installs into a folder
directly on the root of the C: drive, and it operates without errors
regardless of the user level. I’m hence considering this as a viable way to
release my applications in future, since all of them will probably involve
significant interactions with local Access databases.

Are there any implications to doing this do you think, or am I just being
lazy and dodging the security problem completely? Would this approach allow
my application to be used as a gateway by hackers, or will the signing of the
..NET DLLs prevent them from being tampered with? The suggestion of installing
static files to the program files directory and Access data files to user
specific folder is not viable in my case, since different users need to be
able to share data in these databases.

The only avenue for research is a type of folder that I’ve noticed can be
installed by an InstallShield installer. This is called [DATABASEDIR], and I
wondered if it’s Microsoft’s solution to the problem I’m facing? Do you think
this could help me?

Any thoughts?!

Thanks in advance!

Steve.

P.S. Apologies if this post is now off-topic. I’d be happy to post elsewhere
if you think it’s a good idea.


"Jeffrey Tan[MSFT]" said:
Hi Patrice,

Thanks for your feedback.

Yes, just as other community members pointed out, your code runs without
error because of the virtualization feature of Vista User Account
Control(UAC). That is, any write operation to the Program Files directory
is redirected to per-user local profile directory. If you are using Windows
Explorer to find the file, you will see a "Compatibility Files" button in
the toolbar. If you click this button, it will help you to navigate to the
redirected folder.

The best practise is using Environment.SpecialFolder.ApplicationData to
find the per-user application data folder path and save the data there.
Please see my original thread below for more information:
http://www.thescripts.com/forum/thread638856.html

Finally, if you are interested to understand the Vista new UAC security
enhancement, I highly recommend "Mark Russinovich"'s online video below, it
is almost the best tech talk on UAC topic(level 400):
"Windows Vista User Account Control Internals"
http://www.microsoft.com/emea/itsshowtime/sessionh.aspx?videoid=360

Hope it helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Duniho

Hi guys,

Thanks for your first class assistance everyone!

It feels a little like I’ve opened a can of worms here, and from my
point of view, I’m not sure how to proceed.

Yup, you have opened a can of worms. :) But as you've noticed, there's
plenty of people here happy to tell you how they think you should write
your program. :)
The reason for my original question is that I’ve written a .NET
application that installs to the Program Files directory.

Okay so far. :)
The application interacts with
Access databases installed into folders below the folder where the .NET
executable is installed. These databases are used to store essential
application settings; these settings are extremely dynamic in nature. I
use the System.Data.OleDb namespace to interact with these databases. My
installer has been created using the installer project in Visual Studio.

You've already strayed a bit here. :) It is not at all clear to me that
using an Access database to maintain application settings is the right
approach. There are a number of relatively standard methods for
maintaining application settings, none of which involve an Access
database, nor storing the settings under the Program Files directory
hierarchy.
If I install the application to the program files folder on an XP
machine, under a non-administrative account, I get all sorts of
problems, the first of which being an MDAC error. This is the case
even if I run the install using administrator rights, having logged
on as a normal user.

Here, I think you should be more clear about exactly what problems occurs,
at what stage, and exactly how you are doing things.

For example, what do you mean by "using administrator rights, having
logged on as a normal user"? Under XP, not using an administrator
account, the usual way to run a program with "administrator rights" is to
use the "Run As..." menu command from the right-click menu. Doing this
will run the program as if you had logged in as an administrator (assuming
you select an administrator account of course), but you will only have
administrator rights during that execution session.

This means that if you run the setup as an administrator, you should not
get any errors that you would not get having logged in as an administrator
directly, *while the setup is running*. But once setup is done, you're
back to being a non-administrator user and all the same security
restrictions apply.

If you can run setup as an administrator account without getting an MDAC
error, then I don't see any obvious reason you should get that error
running the setup under the same administrator account using the "Run
As..." command. That means that absent any more detailed explanation, I
can only assume that the errors you're getting happen either because you
aren't actually running "using administrator rights", at least not at the
moment that the error happens.
There are literally loads of applications out there that run without
problem under a normal user account, and still manage to create folders
under their main folder. This is the case with most modern games.
However, I have
realised that the default install location for most games is to put them
at C:\ level, completely ignoring the Program Files directory. It would
seem
that games manufacturers have come to the conclusion that the only way
to be sure their applications can do all they need to without getting
security
problems is to forget about the program files folder altogether.

Your impression of what happens with "modern games" is incorrect. It is
true that lots of applications run without problem under a normal user
account. But they do so by following the rules, and not looking for write
access to the Program Files directory during normal execution.

It is also true that some applications bypass the security model by
installing to the root directory. However, any "modern application" that
does this is not following the rules and is likely to break when users do
something it doesn't expect, even if the user is within their rights to do
so. This includes changing the permissions of the root directory to
prevent non-administrator accounts from having write access, as well as
changing from the default installation directory to one under the Program
Files tree.

A correctly designed application (game or otherwise), will install into
the appropriate applications path (generally this is "C:\Program Files",
but this is user-configurable and the setup program should respect the
user configuration). It will *not* write to that installation path under
normal circumstances. If it does need to write to the installation path
(for example, the application supports some kind of automatic update
mechanism), it will require being run as an administrator or will prompt
the user to provide administrator credentials.

It is true that a number of applications exist that do not follow this
model, games being particularly bad offenders. But that doesn't make it
the right thing to do, and any game that doesn't follow the model
introduces a variety of problems (one of the most common being the
assumption that only one user will ever run the application, and that user
will always be an administrator).

For the record, I have installed a number of recently published games that
follow a correct user rights model, installing under "Program Files" and
requiring administrator access rights only for administrator-type actions
(such as updating the game). Granted, I've also installed a number of
recently published games that don't, but that doesn't make it correct
behavior. It just means those games aren't doing it right.
I have made a version of my application that also installs into a folder
directly on the root of the C: drive, and it operates without errors
regardless of the user level. I’m hence considering this as a viable way
to release my applications in future, since all of them will probably
involve significant interactions with local Access databases.

Bad idea. Sorry...you asked. :)
Are there any implications to doing this do you think, or am I just being
lazy and dodging the security problem completely? Would this approach
allow my application to be used as a gateway by hackers, or will the
signing of the .NET DLLs prevent them from being tampered with? The
suggestion of installing static files to the program files directory and
Access data files to user
specific folder is not viable in my case, since different users need to
be able to share data in these databases.

See above for some examples of problems that might be caused. In
addition, you are right to have concerns about the security implications.
I don't think you should rely on the .NET signing to protect your
application from attacks from hackers. Granted complete access to the
entire installation tree, there may be ways to work around that signing.

If you absolutely *must* store your application settings in Access
databases, the "right way" to do it is to keep those databases under the
"All Users\Local Settings" directory tree. This directory tree should be
accessible by all users, and doesn't require that those users have write
access to where the code for your application resides.

Ideally, you would not have application settings that when changed by one
user would affect other users. Frankly, it's just not a good idea
generally. I can't rule out the possibility that you have one of those
rare instances where it makes sense, but just as it seems unlikely to be
that an Access database is the right way to store the settings, it also
seems unlikely to me that having any non-administrator user on the
computer being able to change settings in a way that affects other users
is the correct model.

But if you must do it this way, the "All Users\Local Settings" directory
is the place to do it.

Pete
 
G

Guest

Hi Pete, and thanks for your answers.

OK, I really do need to use an Access database, since as well as settings
(in the sense of the sort of thing you’d put in an application configuration
file), I also need to store a lot of data that the user downloads or creates.
This data could run into hundreds of rows. Using a “proper†data engine like
SQL Server is not an option, since we can’t enforce that our users have this
engine installed. The data needs to be queried and manipulated, so Access
seemed like the obvious choice. Sure, we could have gone with some kind of
text file solution or some other third party storage mechanism, but we would
still need write access to the directory in which the storage takes place.

One thing that the Access database does is maintain settings relating to the
product being unlocked. The product has a number of features, and the
database is used to keep track of the features the user has paid for, and
hence can use. Licensing is done per-install, so these types of settings need
to be shared between all users that log on and access the system.

I’d appreciate alternative suggestions to achieve the above if you can think
of any, especially if they could potentially circumvent our security issues.

I’m going to make some mock up applications and installers now so I can
report simple steps to reproduce any problems I’ve been facing. I’ll get back
to you later today. I’ll also try to mock up an application that writes the
Access database to the “All Users\Local Settings†folder. Off the top of your
head, do you know how to get a .NET installer to write to this folder?

I’m aware of the “Run as…†feature, although I access this a different way.
If you log on as a standard user, and double click on a SetUp file, you get a
dialog box asking which account to run the install under. I supply the
administrator details here.

Thanks again!

Steve.
 
G

Guest

Hi Pete,

The MDAC error I mentioned was a red-herring. The problem is down to
permissions again!

I’ve mocked up a little test Windows application and installer which
demonstrates the problems I’ve been experiencing. The application is a simple
form that interacts with an Access database. I’ve configured the application
so that the database can be tested from different locations. The installer is
equally basic, and installs only the application, the .NET 1.1 Framework,
MDAC and the Access database. I test the installer on a VM Ware virtual
machine, which is returned to a clean state after every test.

Test details:

1) Access database is configured to install to:
[CommonAppDataFolder]\Test\Test.mdb.
2) Application is configured to install to a folder below the Program Files
folder (installer default).
3) I run the installer on the VM machine. Installer prompts for
administrator details.
4) Installation completes successfully. Note that I choose “all users†and
NOT “just meâ€.
5) Confirm that the Access database has been copied to ‘C:\Documents and
Settings\All Users\Application Data\Test\Test.mdb’ - it has!
6) Confirm that the application has been copied to ‘C:\Program
Files\ABC\Installer2’ - it has!
7) Start the application and make sure it is looking for the Access database
in the correct location. All fine.
8) When I click the test buttons to start interacting with the Access
database, I get an error: ‘The Microsoft Jet database engine cannot open the
file ‘C:\documents and settings\all users\application data\test\test.mdb’. It
is already opened exclusively by another user, or you need permission to view
its data.’ - Note that the database is not opened elsewhere, so it’s the
later case.

So, for some reason, the application cannot access the database, even in the
All Users\Application Data folder. This is doubly annoying, since if I
install the application and database to a folder at the root of C (for
instance, C:\Test), everything is fine. In fact, in this case, you can even
run the installer successfully as a standard user!

Back to square one again! Any thoughts?!

Many thanks,

Steve.
 
G

Guest

Apologies for barrage of postings!

Perhaps I’m going about this the wrong way? Rather than forcing the machine
to allow the .NET code to do what it needs to, is it possible to raise the
permissions of the .NET code so that it can do what it needs to? I’ve had a
quick look at the .NET Configuration options, and there doesn’t seem to be a
way to specifically say that assembly X can write to folder Y. Is this
possible?
 
P

Peter Duniho

[...]
8) When I click the test buttons to start interacting with the Access
database, I get an error: ‘The Microsoft Jet database engine cannot open
the file ‘C:\documents and settings\all users\application
data\test\test.mdb’.
It is already opened exclusively by another user, or you need permission
to view its data.’ - Note that the database is not opened elsewhere, so
it’s the later case.

Are you sure the database is not opened elsewhere?

It seems to me that the more correct way to establish that "you need
permission to view its data" is to look at the permissions directly. That
is, check the "Security" tab in the file properties dialog for the related
directories and files and double-check what permissions are granted.

If you find that the permissions aren't sufficient, then you can more
confidently focus in on that question, trying to understand why in that
directory all users still don't have access when normally they would.

One thing I can say for sure: the last thing this world needs is another
application that doesn't follow the correct Windows security model. :)
There are "approved" mechanisms for sharing application data between
users, and if those mechanisms aren't working for you it's better to put
more effort into figuring out why, rather than working around them by
using some presumed back door that will not necessarily work on all
computers for all users. In addition to the obvious benefits for the
end-user, I think you will find that in the long run, doing so improves
the longevity of your code and reduces your support costs.

Pete
 
J

Jeffrey Tan[MSFT]

Hi Pete,

Thanks for your detailed feedback.

Yes, normal user does not have write permission to the "All Users"
directory, so this error is expected. I have original pointed this out in
the last reply of link below:
http://www.thescripts.com/forum/thread638856.html

What looks strange is the full path of your test.mdb. Actually, I can not
find the full "C:\documents and settings\all users\application data\"
directory on my Vista machine. Based on my experience, "C:\documents and
settings" is not intended to be used in Vista, "C:\Users" is the users
profile path. However, still, the normal users can only have write
permission to its own directory under "C:\Users". Also,
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
points to "C:\ProgramData" directory on Vista, which is also read-only to
the normal user.

Let's go back to your problem. Yes, Vista UAC has setup application
detection mechanism, so your setup application can be elevated as
Administrator account and write to Program Files without any problem.
However, I am not sure if I have missed any reason in long posts; why
"different users need to be able to share data in these databases" in your
application? Based on my experience on game progress, we seldom need one
user's setting to affect another user on the same machine, so I do not
understand your requirement quite well currently. If I missed any reason,
please feel free to point out, thanks.

In your scenario, if your application really has requirement of sharing the
writting between all users, we have 2 options:
1. Creating a common data directory under "C:\" which grants write
permission to "Users" group. This will allow all users to write to this
directory, and all users can share the Access database.
2. Coding a separate Windows Service which runs under a high priviledge
account, such as LocalSystem or Administrator. Your normal user application
can user some type of inter-process communication technology to ask write
request to the Windows Service, and the Windows Service with high
priviledge work on behalf of your application to write to the
"C:\ProgramData" directory.(which is read-only to your normal user account)

Comment:
1. Since you are sharing writting data between all users, a normal user may
modify the shared data to force another user to load it. This is a type of
attack pattern, which I forget its name.
2. This is a better solution, since we separate the high priviledge
operations/code from the normal operation code. Also, by defining a
well-defined interface between the normal game application and the Windows
Service, we expect it to be safe. In this mode, the Windows Service
application is called a permission broker application. IE7 protection mode
uses 2 broker applications for high priviledge write operation which idea
is the same here. Please refer to the "Understanding Protected Mode"
section in link below to see these 2 broker processes:
"Understanding and Working in Protected Mode Internet Explorer"
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/d
nwebgen/ProtectedMode.asp

Finally, there is no way to elevate the .Net code permission
programmatically, or the hacker's code can leverage it to defeat the DACL
checking, which is certainly a security hole.

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
P

Peter Duniho

Yes, normal user does not have write permission to the "All Users"
directory, so this error is expected. I have original pointed this out in
the last reply of link below:
http://www.thescripts.com/forum/thread638856.html

Sorry...you're right. I must have gotten the general "All Users"
permissions mixed up with the "Documents" folder under that one (which
does default to being open to all members of the "Users" group).

Still, the application's setup program could create a special folder under
"Application Data" that does have the "Users" permissions set to including
writing. IMHO, this is a better solution that creating a new directory at
the root level of the drive, and should still be applicable under Vista (I
have limited experience there, but it's my recollection that it still has
a general "all users" sort of directory somewhere).

I still think it's not a great idea to have users generally sharing data.
It seems to me that allowing one user to modify data used by another user
is a security issue, as well as simply being a usability issue. If there
are data that need to be configured for all users, that data should be
configured by an administrator. For example, installing license keys that
unlock functionality, or downloading data that enables or supports some
features. Once an administrator has done these operations, then all users
can take advantage of them having only read access to it.

Pete
 
G

Guest

Hi guys,

Thanks for your answers.

Pete: The Access database definitely isn’t opened elsewhere. I run the
installer on a clean VM Ware virtual machine and kick if off for the first
time. The test code only connects to the database when the test button is
clicked, so there’s no way it could be opened elsewhere. As Jeffery points
out, the “All Users†folder you recommended isn’t available to a standard
user. Point taken about the World not needing another application installed
in a non-conventional way. However, my boss would rather have an application
installed in a non-conventional way than not at all! I will endeavour to find
a more standard solution, but if I can’t, it’s going to be the root directory
solution.

All: Sorry for the confusion regarding the documents and settings folder not
being on Vista. I actually decided to perform my virtual tests on XP for now,
since, as has been pointed out, the same security problems exist on XP and
Vista (and probably older operating systems too). Ultimately, I require a
solution that works for all operating systems that support .NET. I will be
running the tests on my virtual Vista machine too.

Jeffrey: I do definitely need the database in the Access database to be
common to all users (i.e. not duplicated) and editable by all users. I think
I’ve explained this above. There are many reasons for this, one being: If
user A creates data, user B needs to be able to view and edit that data as
well. For instance, if user A enters a product key to unlock features, a list
of these unlocked features is stored in the Access database (encrypted and
tamper-proof!). When user B logs on, they must also be able to access the
features unlocked by A without re-entering the product key. As I say, there
are many other reasons why we need to have a single shared writable data
store, due to the nature of our product. We’ve made the data access layer
that interacts with Access database completely thread safe, since it is
possible that two or more threads operating within the UI may try to use the
Access database at the same time, so we’ve no worries there. It is worth
noting that the data in the database can (and will) change at any time, and
so using a .NET config file is not an option, and we can’t go with an
in-memory solution (and write to data store later) since the volume of data
we’re storing is too large for this. (By the way, we’re not actually writing
a game; I’ve been referring to games because they generally do the same thing
we’re trying to achieve.)

Pete: It is also not viable to have the shared data edited under
Administrator rights, and then have users on read-only access. Many of our
customers have small office setups, and contract their IT functions out to
third parties. Office based staff do not generally have access to
administrator passwords (since they are not trusted!), and so they would have
to get their IT providers to make a site visit every time they wanted to
change the data in the database. Depending on the contract, each visit could
be costly. Even if we only stored features in the database, it would
discourage users for purchasing new features if they had to get their IT out
every time they needed to enter a new product key! As I’ve mentioned though,
the Access database also contains data created by users as they use the
product, and it is not uncommon for a hundred or so records to be created or
edited each time the product is used.

We have no other alternative to using a shared Access database, so can we
take that as a given from now on? (Of course, I’d be interested to hear about
other solutions, but we can’t escape the fact that we need a shared, writable
data store.)

I like the idea of writing a Windows Service to act as a shared data
manager, although I think this is overkill for what we need to do. I’m
guessing that adding a Windows Service to our application would cause us
issues further down the line, since our users install the product themselves
from a CD. I dread to think what sort of installation issues they might
encounter! Am I being over pessimistic here?

The idea of keeping the Access database near the root of C:\ is a nice
compromise: keep the code secure in Program Files, and only reduce the
security on items that need to be shared. Pete: How could I install the
Access database to the “Application Data†folder at install time AND ensure
that all users can access this directory? Is it possible to alter directory
permissions at install time using the .NET installer?

Apologies for my naivety here; I do appreciate your time in helping me.

Cheers,

Steve.
 
P

Peter Duniho

[...]
We have no other alternative to using a shared Access database, so can we
take that as a given from now on? (Of course, I’d be interested to hear
about other solutions, but we can’t escape the fact that we need a
shared, writable data store.)

For any given task in computer programming there are often dozens, if not
innumerable, ways to accomplish the task. I think it is trivially obvious
that you do have other alternatives to using a shared Access database.
That said, if a shared Access database is what you want, it should be
possible.
I like the idea of writing a Windows Service to act as a shared data
manager, although I think this is overkill for what we need to do. I’m
guessing that adding a Windows Service to our application would cause us
issues further down the line, since our users install the product
themselves from a CD. I dread to think what sort of installation issues
they might encounter! Am I being over pessimistic here?

Yes. Lots of consumer software installs services all the time.
Installing a service is no more scary than installing any software (though
I admit, I have used software that frankly makes me nervious about having
it on my computer, due to various problems with the software's design).

For that matter, if you're going to install a service, it seems to me that
you might find it a viable solution to just go ahead and install a version
of SQL Server (I'm not sure, but maybe the "Express" version, which is
available at no cost, can be redistributed?) and then run a real database
with real shared-user functionality.
The idea of keeping the Access database near the root of C:\ is a nice
compromise: keep the code secure in Program Files, and only reduce the
security on items that need to be shared. Pete: How could I install the
Access database to the “Application Data†folder at install time AND
ensure that all users can access this directory? Is it possible to alter
directory permissions at install time using the .NET installer?

It is definitely possible. I have very little experience with writing
installation software though, so I can't offer much advice as to how you'd
integrate the implementation into your setup program. I assume it would
involve writing some sort of custom action that gets executed after all
your files are installed.

As far as how to programmatically change file permissions, you should be
able to use the SetAccessControl() method in the System.IO.File class.
Actually, I haven't played with this much either, but it looks to me as
though what you'd want to do is call GetAccessControl() to obtain the
current settings, then add the "Users" group to that ACL, and finally call
SetAccessControl() to update the ACL for the file.

Note that the best approach would be to change only the permissions on the
file you really want to be shared. You could instead share a whole
directory, but then that opens up a new place for bad software to write
things where it shouldn't.

Pete
 
G

Guest

Hi Pete,

Thanks again!
For any given task in computer programming there are often dozens, if not
innumerable, ways to accomplish the task. I think it is trivially obvious
that you do have other alternatives to using a shared Access database.
That said, if a shared Access database is what you want, it should be
possible.

Sorry, I didn’t mean to sound off. Of course, you’re right, there are many
ways to skin a cat! However, no matter which solution we go for, we’re
inevitably going to need permissions to write to the hard disk, so the
problem is still the same.
Yes. Lots of consumer software installs services all the time.
Installing a service is no more scary than installing any software (though
I admit, I have used software that frankly makes me nervious about having
it on my computer, due to various problems with the software's design).

Although I’ve written Windows Services before, I’ve never deployed them on a
disk and let the end user install them on their own. I was just worried that
I was opening up more scope for errors. The development on the current
project has probably gone too far now to include a Windows Service, although
I will definitely use that approach next time. We have already written a
custom Windows messaging architecture to allow cross process communication,
so we’re half way there to being able to use a Windows Service.
For that matter, if you're going to install a service, it seems to me that
you might find it a viable solution to just go ahead and install a version
of SQL Server (I'm not sure, but maybe the "Express" version, which is
available at no cost, can be redistributed?) and then run a real database
with real shared-user functionality.

True, and yes, we could redistribute the Express version for free. However,
I suspect that the average specification of our end users machines would make
this an impossibility, but good idea though. We probably won’t have room on
the disk for the installation either!
It is definitely possible. I have very little experience with writing
installation software though, so I can't offer much advice as to how you'd
integrate the implementation into your setup program. I assume it would
involve writing some sort of custom action that gets executed after all
your files are installed.

OK, no worries. I’ll create a post on a suitable forum.
As far as how to programmatically change file permissions, you should be
able to use the SetAccessControl() method in the System.IO.File class.
Actually, I haven't played with this much either, but it looks to me as
though what you'd want to do is call GetAccessControl() to obtain the
current settings, then add the "Users" group to that ACL, and finally call
SetAccessControl() to update the ACL for the file.

I’ll look into this too.

I think that just about wraps it up then! Thanks to everyone for their
valuable support. My knowledge of installers and Windows permissions has
taken a leap forward!

All the best,

Steve.


Peter Duniho said:
[...]
We have no other alternative to using a shared Access database, so can we
take that as a given from now on? (Of course, I’d be interested to hear
about other solutions, but we can’t escape the fact that we need a
shared, writable data store.)

For any given task in computer programming there are often dozens, if not
innumerable, ways to accomplish the task. I think it is trivially obvious
that you do have other alternatives to using a shared Access database.
That said, if a shared Access database is what you want, it should be
possible.
I like the idea of writing a Windows Service to act as a shared data
manager, although I think this is overkill for what we need to do. I’m
guessing that adding a Windows Service to our application would cause us
issues further down the line, since our users install the product
themselves from a CD. I dread to think what sort of installation issues
they might encounter! Am I being over pessimistic here?

Yes. Lots of consumer software installs services all the time.
Installing a service is no more scary than installing any software (though
I admit, I have used software that frankly makes me nervious about having
it on my computer, due to various problems with the software's design).

For that matter, if you're going to install a service, it seems to me that
you might find it a viable solution to just go ahead and install a version
of SQL Server (I'm not sure, but maybe the "Express" version, which is
available at no cost, can be redistributed?) and then run a real database
with real shared-user functionality.
The idea of keeping the Access database near the root of C:\ is a nice
compromise: keep the code secure in Program Files, and only reduce the
security on items that need to be shared. Pete: How could I install the
Access database to the “Application Data†folder at install time AND
ensure that all users can access this directory? Is it possible to alter
directory permissions at install time using the .NET installer?

It is definitely possible. I have very little experience with writing
installation software though, so I can't offer much advice as to how you'd
integrate the implementation into your setup program. I assume it would
involve writing some sort of custom action that gets executed after all
your files are installed.

As far as how to programmatically change file permissions, you should be
able to use the SetAccessControl() method in the System.IO.File class.
Actually, I haven't played with this much either, but it looks to me as
though what you'd want to do is call GetAccessControl() to obtain the
current settings, then add the "Users" group to that ACL, and finally call
SetAccessControl() to update the ACL for the file.

Note that the best approach would be to change only the permissions on the
file you really want to be shared. You could instead share a whole
directory, but then that opens up a new place for bad software to write
things where it shouldn't.

Pete
 
P

Peter Duniho

[...]
True, and yes, we could redistribute the Express version for free.
However, I suspect that the average specification of our end users
machines would make this an impossibility, but good idea though.
We probably won’t have room on the disk for the installation either!

For the record, the first computer I put VS Express on, including SQL
Express, was a 550Mhz PIII. The IDE was a little on the sluggish side,
but other than that everything ran just fine (and the IDE was still
usable). IMHO, don't make assumptions about what is too slow and what's
not, at least not when the supposedly "too slow" solution is in other ways
superior. Don't rule it out until you've tried it.

Space on the installation disk is another matter...can't help you with
that. But optical media is cheap. You could just include another disk.
:)

Pete
 
G

Guest

Good point about making assumptions. However, our marketing people are pretty
clear that we we must fit everything onto one disk! I'll give it a go all the
same.

Peter Duniho said:
[...]
True, and yes, we could redistribute the Express version for free.
However, I suspect that the average specification of our end users
machines would make this an impossibility, but good idea though.
We probably won’t have room on the disk for the installation either!

For the record, the first computer I put VS Express on, including SQL
Express, was a 550Mhz PIII. The IDE was a little on the sluggish side,
but other than that everything ran just fine (and the IDE was still
usable). IMHO, don't make assumptions about what is too slow and what's
not, at least not when the supposedly "too slow" solution is in other ways
superior. Don't rule it out until you've tried it.

Space on the installation disk is another matter...can't help you with
that. But optical media is cheap. You could just include another disk.
:)

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top