VB6/MS Access unusual behaviour with saved records - vb6

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.

Related

How to write files that are read only for other users and processes on Windows

I am working on a Windows application written in Java that writes its project specific information and settings in specific project files. I wish that only this application can read and modify the project files and settings and these files can not be read or edited via some text editor by the user or written to by some other application. I was thinking of adding obfuscation to prevent information access but how can i prevent any other user process from writing to the files.
As long as your application is running, you can just keep the file open in your application. You can specify how other processes can access the file while you have open when opening the file (the default usually is that no one else can write it, though)¹.
However, if your application isn't running all the time that won't work, obviously. The usual way to solve this is to run the application under a separate user account and only give that account permission to modify the files. That sort of thing works for servers and services, of course, but is rather rare for a normal user-facing application, though.
You can employ obfuscation, or store the contents elsewhere as well (e.g. another file in another place, registry, ADS, ...) and try recovering from a mismatch. But fundamentally, barring separate user accounts, you have no way of actually forbidding access to a file. Such things cannot be done with process-level granularity on Windows.
¹ I'm not sure how much control Java gives you over this, though. A quick look at FileInputStream seems to give you absolutely no control over the handle's sharing policy. You can use native code to open the file, though, though I'm not sure right now how to pass that to the usual Java I/O classes. It could be difficult.

File not written to by System.Data.SQLite on windows share after network failure

I have the following scenario:
WPF Application using SQLite-file per System.Data.SQLite on a windows-share as backend. Client is Windows 7 Home Edition
A user reported, that she was using the software, saving the new data she entered, but then after a while when she re-visited the software, some of her stuff was gone.
She said the session lasted until about 11:50am - the timestamp on the SQLite file in question was 10:55am. I have a logfile in the same network share, it is written to using a filewriter with autoflush.
The logfile looks normal until 10:55am, then there is one line with rubbish (looks like several lines written together in one), then goes on as normal.
Clearly the network (or maybe the drive) must have had a hiccup at that time. Miraculously my application just continued as normal. No exceptions were thrown, according to the logfile all transactions are "completed". No journal file remains to tell the tale. This behaviour - although wonderous in itself - is not appreciated by the user :)
My question: what happened here and how can I prevent it in the future? Did Windows 7 cache the file in the standby list and not care at all about comitting the changes to the actual disk? Why is my application or the SQLite provider unaware of this?
I will now build a confirmation mechanism that checks the timestamp on the backend file to see if it was actually changed at all after the last transaction, but that seems a bit silly. Just as silly as being very pedantic with catching exceptions when they are not being thrown :)
Thank you
TL;DR
SQlite file shows no changes after momentarily hardware (network or drive) failure, but the application seemingly continues to function and no exceptions are thrown by System.Data.SQLite.
See section 3 of How To Corrupt An SQLite Database File; it appears that Windows did not sync the network share when SQLite told it to.

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.

File Access Times in Windows + NTFS

I am trying to figure out when and how does Windows update File Access Times on files.
First of all, most Windows installs come with File Access Times disabled for performance reasons, so before wrapping your head around it here is what you need to do in order to activate last access times on NTFS file systems: modify the key [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem] value name NtfsDisableLastAccessUpdate to DWORD 0 value data(if it is set to 1 of course). If it doesn't exist just create it.
Upon reading File Times article on MSDN i am still in doubt as to how Windows updates access times.
My questions are as follow:
Do access times update upon issuing a WinApi CreateFile() with FILE_READ_ATTRIBUTES ? In my case, while doing it programmatically, it doesn't. Opening up the File Properties dialog of that file through the Explorer Shell does update the access time.
Do access times update upon issuing a WinApi ExtractIconEx() to read an icon from a file?
In my case doing so programatically, it doesn't. Opening up the File Properties dialog of that file through the Explorer Shell does update the access time.
If you ask me, both of those cases should update the file access times, but it seems to me that direct WinApi calls don't update them or Window/NTFS driver really lags behind, while operating on files from Windows Explorer do update pretty well. What do you think is or could be the issue here?
As a side note, i did do CloseHandle() as per:
The only guarantee about a file
timestamp is that the file time is
correctly reflected when the handle
that makes the change is closed.
My end conclusion is that, indeed the opinions lying around the web are true and Windows does update File Access Times in a random fashion and thus one really shouldn't in no way depend on Windows File Access Times.
Off-topic rant: Sorry forensics guys, you'll have to prove access times using another method or you can have your case invalided in seconds. :P
No, accessing the metadata of the file isn't going to change the last access time (name, attributes, timestamps). Wouldn't work well in practice, just looking at the directory with Explorer would change it. You have to actually open the file. ExtractIconEx() would normally be an excellent candidate, except that Windows can play tricks with it. A hidden desktop.ini file can redirect the icon to another file.
Using the last access time is pretty worthless for forensics. You'd need a file system filter driver. Similar to the one embedded in SysInternals' ProcMon utility. It might be using ETW btw, that got pretty powerful at Vista time. Nevertheless, your project just got 10 times more complicated.

Microsoft JET SQL Query Logging or "How do I debug my customer's program?"

The problem:
We use a program written by our biggest customer to receive orders, book tranports and do other order-related stuff. We have no other chance but to use the program and the customer is very unsupportive when it comes to problems with their program. We just have to live with the program.
Now this program is most of the time extremely slow when using it with two or more user so I tried to look behind the curtain and find the source of the problem.
Some points about the program I found out so far:
It's written in VB 6.0
It uses a password-protected Access-DB (Access 2000 MDB) that is located a folder on one user's machine.
That folder is shared over the network and used by all other users.
It uses the msjet40.dll version 4.00.9704 to communicate with access. I guess it's ADO?
I also used Process Monitor to monitor file access and found out why the program is so slow: it is doing thousands of read operations on the mdb-file, even when the program is idle. Over the network this is of course tremendously slow:
Process Monitor Trace http://img217.imageshack.us/img217/1456/screenshothw5.png
The real question:
Is there any way to monitor the queries that are responsible for the read activity? Is there a trace flag I can set? Hooking the JET DLL's? I guess the program is doing some expensive queries that are causing JET to read lots of data in the process.
PS: I already tried to put the mdb on our company's file server with the success that accessing it was even slower than over the local share. I also tried changing the locking mechanisms (opportunistic locking) on the client with no success.
I want to know what's going on and need some hard facts and suggestions for our customer's developer to help him/her make the programm faster.
To get your grubby hands on exactly what Access is doing query-wise behind the scenes there's an undocumented feature called JETSHOWPLAN - when switched on in the registry it creates a showplan.out text file. The details are in
this TechRepublic article alternate, summarized here:
The ShowPlan option was added to Jet 3.0, and produces a text file
that contains the query's plan. (ShowPlan doesn't support subqueries.)
You must enable it by adding a Debug key to the registry like so:
\\HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\JET\4.0\Engines\Debug
Under the new Debug key, add a string data type named JETSHOWPLAN
(you must use all uppercase letters). Then, add the key value ON to
enable the feature. If Access has been running in the background, you
must close it and relaunch it for the function to work.
When ShowPlan is enabled, Jet creates a text file named SHOWPLAN.OUT
(which might end up in your My Documents folder or the current
default folder, depending on the version of Jet you're using) every
time Jet compiles a query. You can then view this text file for clues
to how Jet is running your queries.
We recommend that you disable this feature by changing the key's value
to OFF unless you're specifically using it. Jet appends the plan to
an existing file and eventually, the process actually slows things
down. Turn on the feature only when you need to review a specific
query plan. Open the database, run the query, and then disable the
feature.
For tracking down nightmare problems it's unbeatable - it's the sort of thing you get on your big expensive industrial databases - this feature is cool - it's lovely and fluffy - it's my friend… ;-)
Could you not throw a packet sniffer (like Wireshark) on the network and watch the traffic between one user and the host machine?
If it uses an ODBC connection you can enable logging for that.
Start ODBC Data Source Administrator.
Select the Tracing tab
Select the Start Tracing Now button.
Select Apply or OK.
Run the app for awhile.
Return to ODBC Administrator.
Select the Tracing tab.
Select the Stop Tracing Now button.
The trace can be viewed in the location that you initially specified in the Log file Path box.
First question: Do you have a copy of MS Access 2000 or better?
If so:
When you say the MDB is "password protected", do you mean that when you try to open it using MS Access you get a prompt for a password only, or does it prompt you for a user name and password? (Or give you an error message that says, "You do not have the necessary permissions to use the foo.mdb object."?)
If it's the latter, (user-level security), look for a corresponding .MDW file that goes along with the MDB. If you find it, this is the "workgroup information file" that is used as a "key" for opening the MDB. Try making a desktop shortcut with a target like:
"Path to MSACCESS.EXE" "Path To foo.mdb" /wrkgrp "Path to foo.mdw"
MS Access should then prompt you for your user name and password which is (hopefully) the same as what the VB6 app asks you for. This would at least allow you to open the MDB file and look at the table structure to see if there are any obvious design flaws.
Beyond that, as far as I know, Eduardo is correct that you pretty much need to be able to run a debugger on the developer's source code to find out exactly what the real-time queries are doing...
It is not possible without the help of the developers. Sorry.

Resources