How to get (programatically) the location of a Windows UAC virtualized file? - winapi

I have a 32-bit windows old application (with the C/Win32 source) that creates its data file in the same folder where the executable is.
Because the application has no installation program and the user can place the executable wherever he/she wants, the application has a dialog to inform the user where its data is located.
But under Microsoft Vista/Seven if the user puts the application in the Program Files or any other system-protected folder the data file gets virtualized and moved to a virtual-store.
If, under Vista/Seven, I still want to inform the user where the data file is located:
(without preventing virtualization in the manifest file)
How can I know (programatically) if the data file is virtualized? Or if the folder where the executable is located implies that data file will be virtualized?
Assuming I know the data file is virtualized, how can I know (programatically) the location of the virtual folder, to show it in the information dialog?
I have found the following question very close to what I'm asking but it doesn't show the solution (if any) of knowing when virtualization is taking place for a file, and where it gets virtualized.
How to detect file redirection to the Windows VirtualStore?

Virtualization is transparent to the app. The only way to know whether it is being virtualized is to ask the OS, per the answer in the question you linked to (use GetTokenInformation() with the TokenVirtualizationEnabled flag), but there is no way (that I know of) of asking the OS where the virtualized items are actually stored, as it may be different from one OS version to the next. You will have to do some research and then hard-code the paths for each given OS that your app detects at runtime.
If you are going to update your code to detect virtualization, then you are better off updating the code to play nicer with UAC instead. Stop storing your files where they do not belong, and start storing them where Microsoft wants you to store them. In this case, within the user's profile instead. Use SHGetFolderPath() or related function to locate the user's CSIDL_LOCAL_APPDATA folder (or SHGetKnownFolderPath() on Vista+ to locate the FOLDERID_LocalAppData folder), then create a subfolder underneath it for your app to store its data files in.

Related

Create file or registry key without calling NTDLL.DLL

I know that ntdll is always present in the running process but is there a way (not necessarily supported/stable/guaranteed to work) to create a file/key without ever invoking ntdll functions?
NTDLL is at the bottom of the user-mode hierarchy, some of its functions switch to kernel mode to perform their tasks. If you want to duplicate its code then I suppose there is nothing stopping you from decompiling NtCreateFile to figure out how it works. Keep in mind that on 32-bit Windows there are 3 different instructions used to enter kernel mode (depending on the CPU type), the exact way and where the transition code lives changes between versions and the system call ids change between versions (and even service packs). You can find a list of system call ids here.
I assume you are doing this to avoid people hooking your calls? Detecting your calls? Either way, I can't recommend that you try to do this. Having to test on a huge set of different Windows versions is unmanageable and your software might break on a simple Windows update at any point.
You could create a custom kernel driver that does the work for you but then you are on the hook for getting all the security correct. At least you would have documented functions to call in the kernel.
Technically, registry is stored in %WINDIR%\System32\config / %WINDIR%\SysWOW64\config, excepted your own user's registry which is stored in your own profile, in %USERPROFILE%\NTUSER.DAT.
And now, the problems...
You don't normally have even a read access to this folder, and this is true even from an elevated process. You'll need to change (and mess up a lot...) the permissions to simply read it.
Even for your own registry, you can't open the binary file - "Sharing violation"... So, for system/local machine registries... You can't in fact open ANY registry file for the current machine/session. You would need to shut down your Windows and mount its system drive in another machine/OS to be able to open - and maybe edit - registry files.
Real registry isn't a simple file like the .reg files. It's a database (you can look here for some elements on its structure). Even when having a full access to the binary files, it won't be fun to add something inside "from scratch", without any sotware support.
So, it's technically possible - after all, Windows does it, right? But I doubt that it can be done in a reasonable amount of time, and I simply can't see any benefit from doing that since, as you said, ntdll is ALWAYS present, loaded and available to be used.
If the purpose is to hack the current machine and/or bypass some lack of privileges, it's a hopeless approach, since you'll need even more privileges to do it - like being able to open your case and extract the system drive or being able to boot on another operating system on the same machine... If it's possible, then there is already tools to access the offline Windows, found on a well-known "Boot CD", so still no need to write in registry without any Windows support.

VB6/MS Access unusual behaviour with saved records

I have a VB6 application and it links to a MS Access DB. All records on a data entry screen are written or read using ADO/SQL.
At one user site, (using Win 7 - his UAC was set to the maximum security so to start with, there were errors reading/writing galore! Furthermore the app and Data (sub-folder) folder was set to only read. So once I corrected all of this by changing Security for "All User" to FULL CONTROL, the records were written to the DB. However when I open the MDB from MS Access directly I was unable to see ANY records in any of the 3 tables where the Client entered data from the front end.
So
1. either MS Access is hiding the rows in the table with data and display and blank table or
2. there is a hidden copy of the MDB in the Data sub-folder (as the program check the availability of the MDB file when it starts and if unavailable it posts a Message Box error
Has anyone seen this behaviour and if it is #2, how do I in Win 7 show all files - bear in mind that MDBs are not operating system files so by default should not be hidden. OR is this some AV (Symantec) activity?
Please see this link from Y 2004 which is exactly like my issue - but there was no answer:
http://www.pcreview.co.uk/forums/hidden-records-t1086918.html
Appreciate any help anyone can shed
Regards
Fonz
This sounds like an improperly designed application that puts writable data (an MDB file here) within a protected folder ("Program Files") and is being run with no application manifest stating that it is "Vista aware." If you do this Windows will try to fit a standard set of appcompat shims to the program, and in this case most likely the file virtualization shim is at work.
This results in each user creating private copies of the orginal data within their Virtual Store folder. These private copies are what gets updated.
A proper manifest would result in a fatal runtime error on this security violation instead, making it quicker to understand what is being done wrong and generally leading to a faster resolution.
Things such as INI files, MDB files, and other application resources that must be updated and available to any user of the system should be put into an application-specific folder your installer creates under [CommonAppData]. You installer should set the desired security attributes on the subfolder to contain writable files so that all users have the desired access. The default here is "owner" access which probably is not what you would want (file creator has full access, others have read access).
This works on any version of Windows including Windows 95 with the IE4 Desktop Update. It is fairly easy to accomplish via Installer MSI packages.
Are you 100% certain about which MDB file is being written to? If you are writing then seeing your records in the VB6 but then can't see them in the MDB that you open, it's possible that it's doing it to a different file.
I suggest you use process monitor to verify exactly which file is being written to by the VB6 app. That will allow you to troubleshoot further.
http://technet.microsoft.com/en-us/sysinternals/bb896645
It can be a little busy but it will let you establish exactly which file is being written to regardless of any asuumptions you make about the operation of your code.

Windows - download a file on-demand, when FileNotFound in file system?

I want to put some sort of "hook" into windows (only has to work on Windows Server 2008 R2 and above) which when I ask for a file on disk and it's not there it then requests it from a web server and caches it locally.
The files are immutable and have unique file names.
The application which is trying to open these files is written in C and just opens a file using the operating system in the normal way. Say it calls OpenFile asking for c:\scripts\1234.12.script, and that is there then it will just open it normally. If then it asks for c:\scripts\1234.13.script and it isn't then my hook in the operating system will then go and ask my web service for the file, download it and then return that file as it it were there all the time.
I'd prefer to write this as a usermode process (I've never written a windows driver), it should only fire when files are not found in a specific folder, and I'd prefer if possible to write it in a managed language (C# would be perfect). The files are small (< 50kB) and the web service is fast and the internet connection blinding so I'm not expecting it to take more than a second to download the file.
My question is - where do I start looking for information about this kind of thing? And if anyone has done anything similar - do you know what options I have (eg can it be done in C#?)?
You would need to create a kernel-mode filesystem filter driver which would intercept requests for opening such files and would "fake" those files. I should say that this is a very complicated task even for driver development. Our CallbackFilter product would be able to solve your problem however mechanism for "faking" files is not yet ready (we plan this feature for CallbackFilter 3). Until then I don't know any user-mode solutions (frankly speaking, no kernel-mode solutions as well) that would solve your problem.
If you can change the folder the application is accessing, then you can create a virtual file system and map it to the drive letter or a folder on NTFS drive. From the virtual file system you can direct most requests to/from real disk and if the file doesn't exist, you can download the file and cache it. Our other product, Callback File System, lets you do what I described in user-mode. If you have a one-time task you need to accomplish, and don't have a budget for it, please contact us anyway and maybe we can find some solution. There also exists an open-source solution with similar (but not so comprehensive) functionality named Dokan, yet I will refrain from commenting on its quality.
You can also try Dokan , it open source and you can check its discussion group for question and guides.

Is there a way to lock up a directory with Java?

My app creates a directory(file folder) on C:/ drive, since I don't want to expose all the data in it, and I don't want to encrypt all files in it, I wonder if there is a way to lock the folder up, so only my app can access it, no other person through windows explorer or another program can open the folder, doesn't matter if my app is running or not, is it doable ?
This is inherently impossible.
There is nothing that your program can do on the user's machine that he cannot do himself. (possibly aided by a decompiler and a debugger)
Nope, operating systems just don't provide this type of facility. You can look at file locks (http://en.wikipedia.org/wiki/File_locking) but those are intended to prevent "concurrent access" not this sort of "lock". With that said, you should ask yourself what are you trying to do here, is it securing information (encrypted file) or preventing accidental configuration changes (hiding the directory)?

How to view who has a file open on Windows fileserver

I was contemplating moving to a version control system at work, but the learning curve may be too much for the many copywriters that open simple html files and editt them on our shared development server. The main issue is that sometimes two people will work on the same file (on our development server) at once and overwrite each other.
Is there any extension to Windows explorer that will simply display a lock icon near a shared file that is already in use? For us, something like this maybe be simpler than teaching everyone to develop from their own working copies and use version control clients. I just want a visible warning to users that a file is already in use and should not be worked on. Thanks
There might not even be enough information on the fileserver itself to determine this. For example, if you open an HTML file in Notepad, the file is loaded from disk and then the file is closed. Notepad keeps a copy in memory without keeping the file open on disk. This means that the fileserver doesn't even know that somebody is busy editing the file.
Some text editors might keep the file open but this is probably the exception rather than the rule.
A version control system (Subversion with TortoiseSVN is easy for people to use) allows users to declare their intent without relying on the underlying technology opening files in just the right way. TortoiseSVN displays a "lock" icon beside files that are locked (you lock a file with a "Get Lock" menu option). Files without the lock are marked read-only to help the user know that they aren't ready to edit them yet.

Resources