Help for driver programming - driver

I want to write a driver (in c) that can "catch" the events for reading and writing on hard disk. My problem is that I do not know how can I listen the system bus to treat these events. I use Microsoft DDK.
Thank you!

I think what your looking for is IoAttachDevice(), you can find more information on the routine here.

It is much easier to monitor reads and writes of your applications than those actually happens to the physical media. In other words, it is much easier to write a upper filter driver that sits above the file system driver than playing with the actual driver that handles physical access to the hard disk.
I suggest you browse the examples that come with your version of DDK (or WDK, etc) to see if there's anything similar to what you need. If there is, it's much easier to modify from those instead of starting from scratch.

This is more complicated than you think. This can be done with a SCSI Port Driver. What are you trying to do? Get logical IO or IO on a physical disk?

Related

Can I write a file to a specific cluster location?

You know, when an application opens a file and write to it, the system chooses in which cluster will be stored. I want to choose myself ! Let me tell you what I really want to do... In fact, I don't necessarily want to write anything. I have a HDD with a BAD range of clusters in the middle and I want to mark that space as it is occupied by a file, and eventually set it as a hidden-unmoveable-system one (like page file in windows) so that it won't be accessed anymore. Any ideas on how to do that ?
Later Edit:
I think THIS is my last hope. I just found it, but I need to investigate... Maybe a file could be created anywhere and then relocated to the desired cluster. But that requires writing, and the function may fail if that cluster is bad.
I believe the answer to your specific question: "Can I write a file to a specific cluster location" is, in general, "No".
The reason for that is that the architecture of modern operating systems is layered so that the underlying disk store is accessed at a lower level than you can access, and of course disks can be formatted in different ways so there will be different kernel mode drivers that support different formats. Even so, an intelligent disk controller can remap the addresses used by the kernel mode driver anyway. In short there are too many levels of possible redirection for you to be sure that your intervention is happening at the correct level.
If you are talking about Windows - which you haven't stated but which appears to assumed - then you need to be looking at storage drivers in the kernel (see https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/). I think the closest you could reasonably come would be to write your own Installable File System driver (see https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/_ifsk/). This is really a 'filter' as it sits in the IO request chain and can intercept and change IO Request Packets (IRPs). Of course this would run in the kernel, not in userspace, and normally this would be written in C and I note your question is tagged for Delphi.
Your IFS Driver can sit at differnt levels in the request chain. I have used this technique to intercept calls to specific file system locations (paths / file names) and alter the IRP so as to virtualise the request - even calling back to user space from the kernel to resolve how the request should be handled. Using the provided examples implementing basic functionality with an IFS driver is not too involved because it's a filter and not a complete storgae system.
However the very nature of this approach means that another filter can also alter what you are doing in your driver.
You could look at replacing the file system driver that interfaces to the hardware, but I think that's likely to be an excessive task under the circumstances ... and as pointed out already by #fpiette the disk controller hardware can remap your request anyway.
In the days of MSDOS the access to the hardware was simpler and provided by the BIOS which could be hooked to allow the requests to be intercepted. Modern environments aren't that simple anymore. The IFS approach does allow IO to be hooked, but it does not provide the level of control you need.
EDIT regarding suggestion by the OP of using FSCTL_MOVE_FILE
For simple environment this may well do what you want, it is designed to support a defragmentation process.
However I still think there's no guarantee that this actually will do what you want.
You will note from the page you have linked to it states that it is moving one or more virtual clusters of a file from one logical cluster to another within the same volume
This is a code that's passed to the underlying storage drivers which I have referred to above. What the storage layer does is up to the storage layer and will depend on the underlying technology. With more advanced storage there's no guarantee this actually addresses the physical locations which I believe your question is asking about.
However that's entirely dependent on the underlying storage system. For some types of storage relocation by the OS may not be honoured in the same way. As an example consider an enterprise storage array that has a built in data-tiering function. Without the awareness of the OS data will be relocated within the storage based on the tiering algorithms. Also consider that there are technologies which allow data to be directly accessed (like NVMe) and that you are working with 'virtual' and 'logical' clusters, not physical locations.
However, you may well find that in a simple case, with support in the underlying drivers and no remapping done outside the OS and kernel, this does what you need.
Since you problem is to mark bad cluster, you don't need to write any program. Use the command line utility CHKDSK that Windows provides.
I an elevated command prompt (Run as administrator), run the command:
chkdsk /r c:
The check will be done on the next reboot.
Don't forget to read the documentation.

Getting vlc SAP Broadcast dump

I am receiving SAP broadcasts, which I can normally use and play using the standalone vlc application.
I have been asked to provide a dump of the same. I have 2 questions:
I dont clearly understand what exactly dump is
How can I obtain the same?
There are multiple types of dumps, so you might first find out, what kind of dump is meant. It could be a database dump, which is similar to a backup, but usually it's a memory dump.
A memory dump or crash dump is a copy of the application including its memory at a specific point in time. Usually you want to create a dump exactly at the time an application is crashing or hanging. The dump will then be helpful to find the cause of the problem.
There are many ways to obtain a dump. First, Windows might do that for you, when it asks "Send information to Microsoft". Second, you can create it using Task Manager. Right click a process and choose "Create dump file". Third, there are many tools out there, e.g. Process Explorer or ProcDump, which all have pros and cons and serve different purposes.
To suggest a tool for your specific case, we would need more information. Exact wording might matter in this situation.
Update
In your particular case it looks like SAP means Service Advertising Protocol, which is related to the network. A broadcast is a message which is sent to everybody.
You could capture that one with Wireshark, but you would need a lot of network knowledge to get the filters set up. In this case the term "dump" probably refers to a something similar to a database dump, because SAP uses tables to store lists of services.

Sharing data system wide

Good evening.
I'm looking for a method to share data from my application system-wide, so that other applications could read that data and then do whatever they want with it (e.g. format it for display, use it for logging, etc). The data needs to be updated dynamically in the method itself.
WMI came to mind first, but then you've got the issue of applications pausing while reading from WMI. Additionally, i've no real idea how to setup my own namespace or classes if that's even possible in Delphi.
Using files is another idea, but that could get disk heavy, and it's a real awful method to use for realtime data.
Using a driver would probably be the best option, but that's a little too intrusive on the users end for my liking, and i've no idea on where to even start with it.
WM_COPYDATA would be great, but i'm not sure if that's dynamic enough, and whether it'll be heavy on resources or not.
Using TCP/IP would be the best choice for over the network, but obviously is of little use when run on a single system with no networking requirement.
As you can see, i'm struggling to figure out where to go with this. I don't want to go into one method only to find that it's not gonna work out in the end. Essentially, something like a service, or background process, to record data and then allow other applications to read that data. I'm just unsure on methods. I'd prefer to NOT need elevation/UAC to do this, but if needs be, i'll settle for it.
I'm running in Delphi 2010 for this exercise.
Any ideas?
You want to create some Client-Server architecture, which is also called IPC.
Using WM_COPYDATA is a very good idea. I found out it is very fast, lightweight, and efficient on a local machine. And it can be broadcasted over the system, to all applications at once (to be used with care if some application does not handle it correctly).
You can also share some memory, using memory mapped files. This is may be the fastest IPC option around for huge amount of data, but synchronization is a bit complex (if you want to share more than one buffer at once).
Named pipes are a good candidates for local. They tend to be difficult to implement/configure over a network, due to security issues on modern Windows versions (and are using TCP/IP for network communication - so you should better use directly TCP/IP instead).
My personal advice is that you shall implement your data sharing with abstract classes, able to provide several implementations. You may use WM_COPYDATA first, then switch to named pipes, TCP/IP or HTTP in order to spread your application over a network.
For our Open Source Client-Server ORM, we implemented several protocols, including WM_COPY_DATA, named pipe, HTTP, or direct in-process access. You can take a look at the source code provided for implementation patterns. Here are some benchmarks, to give you data from real implementations:
Client server access:
- Http client keep alive: 3001 assertions passed
first in 7.87ms, done in 153.37ms i.e. 6520/s, average 153us
- Http client multi connect: 3001 assertions passed
first in 151us, done in 305.98ms i.e. 3268/s, average 305us
- Named pipe access: 3003 assertions passed
first in 78.67ms, done in 187.15ms i.e. 5343/s, average 187us
- Local window messages: 3002 assertions passed
first in 148us, done in 112.90ms i.e. 8857/s, average 112us
- Direct in process access: 3001 assertions passed
first in 44us, done in 41.69ms i.e. 23981/s, average 41us
Total failed: 0 / 15014 - Client server access PASSED
As you can see, fastest is direct access, then WM_COPY_DATA, then named pipes, then HTTP (i.e. TCP/IP). Message was around 5 KB of JSON data containing 113 rows, retrieved from server, then parsed on the client 100 times (yes, our framework is fast :) ). For huge blocks of data (like 4 MB), WM_COPY_DATA is slower than named pipes or HTTP-TCP/IP.
Where are several IPC (inter-process communication) methods in Windows. Your question is rather general, I can suggest memory-mapped files to store your shared data and message broadcasting via PostMessage to inform other application that the shared data changed.
If you don't mind running another process, you could use one of the NoSQL databases.
I'm pretty sure that a lot of them won't have Delphi drivers, but some of them have REST drivers and hence can be driven from pretty much anything.
Memcached is an easy way to share data between applications. Memcached is an in-memory key-value store for small chunks of arbitrary data (strings, objects).
A Delphi 2010 client for Memcached can be found on google code:
http://code.google.com/p/delphimemcache/
related question:
Are there any Caching Frameworks for Delphi?
Googling for 'delphi interprocess communication' will give you lots of pointers.
I suggest you take a look at http://madshi.net/, especially MadCodeHook (http://help.madshi.net/madCodeHook.htm)
I have good experience with the product.

Writing data to I/O address

i have a device (cash drawer) and i would like to directly communicate with the device. I know that its on address f1. Also openbit is 01.
As i've understood so far, i'd need to send 1 to memory address f1 and the cash drawer should open. Though using asm, i get access violation. Then again i've read that windows does not let you communicate directly to device i/o addresses (need to use win). What would be the correct way to send the data to that address.
Note that i cannot use drivers, because i can't communicate with the driver inside my application.
Op. system is win7.
Thanks in advance!
There was a library called inpout32.dll that allowed direct port access you can find it here
http://logix4u.net/Inpout32.dll_Discussion/write_DELPHI_for_inpout32.dll.html
But i don't know if supports windows 7.
In addition to the excellent suggestions above, check out this delphi code for writing and reading I/O. We have used the GWIOPM to do what you are asking, but note that it will be ok for 32-bit versions of Windows up to W7 etc (as is the case for most 'free' drivers). For 64-bit Windows you need a signed kernel driver. For this there are few things available at the moment. We had to write our own.
Why can't you communicate with the driver from your application? It's the best way for ring 3 application to talk with hardware in a safe manner.
However, if you really insist using drivers, you can try going to ring 0 and do direct access. It's much harder than in previous Windows versions (XP and before) but it's possible. I haven't done it myself since I don't have Windows 7, but you can try asking in asm programming forum anywhere.

How do I obtain equipment serial numbers programmatically?

I need to run an equipment audit and to do that I need to obtain the Windows PC, monitor etc. serial numbers.
So I faced with going to each PC and manually writing down the numbers.
Is there a way I can get this programmatically so each user can run a small program and email me the results?
If this information is anywhere, it'd be in WMI (http://en.wikipedia.org/wiki/Windows_Management_Instrumentation) - you could write a VBscript script to query this information and save it to a remote share on a server for example.
Generally no. If your computers are all Dell, though, you might be able to get some information (maybe the serial number?) for the PC itself.
The monitor, if it supports VESA EDID (DDC, EDID, EEDID), may also include a 32 bit serial number - which may or may not have any relation to the serial number printed on the monitor's label. You may be able to access this through the display driver - Windows has access to portions of it (to display monitor resolution and timing) so I expect the manufacturer/model/serial number is stashed somewhere as well.
However, making such a program that would work across all systems and monitors would likely be much more work than simply going to each station and recording it, unless all the systems have the same hardware.
Good luck!
-Adam
I am not quite sure if this is exactly what you want, but there is pay software made by DameWare that allows you to easily remote connect to other machines and get lots of information. I haven't used it much yet, but I think there is a way to make batch scripts so it can go pull information like that for you, or see what apps are installed on the machines. Even worse case though, you don't have to run to each machine. (I am assuming you mean SN like the MS product ID)
WMI is definitely the way to go. You can get quite a bit of useful audit information through that API.
Michael Baird appears to have written a VBS script to read the EDID information. The script reads and parses the monitor EDID information from the registry in order to retrieve asset information.
http://cwashington.netreach.net/depo/view.asp?Index=980&ScriptType=vbscript

Resources