This attribute specifies that the system performs all access checks on the handle. By default, the system bypasses all access checks on handles created in kernel mode.
For information about validating object handles, see Failure to Validate Object Handles. This ensures that the handle is inaccessible to user-mode applications. A driver that shares object handles between kernel mode and user mode must be carefully written to avoid accidentally creating security holes. Here are some guidelines:.
Create handles in kernel mode and pass them to user mode, instead of the other way around. Handles created by a user-mode component and passed to the driver should not be trusted.
Otherwise, if a user-mode component closes the handle, the reference count goes to zero, and if the driver then tries to use or close the handle the system will crash. If a user-mode application creates an event object, a driver can safely wait for that event to be signaled, but only if the application passes a handle to the event object to the driver through an IOCTL. For Wikipedia, a file descriptor is an index for an entry in a kernel -resident data structure containing the details of all open files.
In POSIX , this data structure is called a file descriptor table, and each process has its own file descriptor table. The user application passes the abstract key to the kernel through a system call, and the kernel will access the file on behalf of the application, based on the key.
The application itself cannot read or write the file descriptor table directly. To clients using the SDK, it should not matter whether a handle is a pointer to a struct, an integer, etc. The only thing that matters to them is that two different handles do not alias the same data type so that they don't incorrectly pass in the wrong handle to the wrong place. Where it matters most to avoid casting is to you, the internal devs. This kind of aesthetic of hiding away all internal names from the SDK is some conceptual aesthetic that comes at the significant cost of losing all type information, and requiring us to needlessly sprinkle casts into our debuggers to get at critical information.
While a C programmer should largely be accustomed to this in C, to require this needlessly is just asking for trouble. In general you want to watch out for those types of developers who put some conceptual idea of purity far above all practical, daily needs. Those will drive the maintainability of your codebase to the ground in seeking some Utopian ideal, making the whole team avoid suntan lotion in a desert out of fear that it's unnatural and may cause a vitamin D deficiency while half the crew are dying from skin cancer.
Even from the strict user-end standpoint of those using the API, would they prefer a buggy API or an API that works well but exposes some name they could hardly care about in exchange? Because that's the practical trade-off. Losing type information needlessly outside of a generic context is increasing the risk of bugs, and from a large-scale codebase in a team-wide setting over a number of years, Murphy's law tends to be quite applicable.
If you superfluously increase the risk of bugs, chances are you'll at least get some more bugs. It doesn't take too long in a large team setting to find that every kind of human mistake imaginable will eventually go from a potential into a reality.
So perhaps that's a question to pose to users. It matters little how much the developer is confident in avoiding bugs. In a team-wide setting, it helps more to think about the weakest links, and at least the easiest and quickest ways to prevent them from tripping. So I'd suggest a compromise here which will still give you the ability to retain all the debugging benefits:. I suspect the real reason is inertia, that's what they've always done and it works so why change it?
The main reason I can see is that the opaque handle lets the designer put anything at all behind it, not just a struct. If the API returns and accepts multiple opaque types they all look the same to the caller and there's never any compilation problems or recompiles needed if the fine print changes. As well, there's no danger of the OS or anything else quietly "fixing" the pointer if it gets passes across boundaries.
The disadvantage of that, of course, is that the caller can feed anything at all into it. You have a 64 bit thing? Shove it into the 64 bit slot in the API call and see what happens. I believe that the attitude stems from a long-time philosophy to defend a C library API from abuse by beginners. This is just to say it has long traditions; I had no personal opinion on whether it's right or wrong. Sign up to join this community. The best answers are voted up and rise to the top. Stack Overflow for Teams — Collaborate and share knowledge with a private group.
Create a free Team What is Teams? Learn more. Why use an opaque "handle" that requires casting in a public API rather than a typesafe struct pointer? Ask Question. Asked 6 years, 4 months ago. Active 6 years ago. Viewed 13k times. I'm evaluating a library whose public API currently looks like this: libengine. Internally, most of these APIs of course cast the "handle" to an internal structure which they've malloc 'd: engine.
So I submitted a pull request, suggesting the following API change after modifying the entire library to conform : libengine. Let's see what others think about this PR. How is an opaque handle better than a named, opaque struct?
Improve this question. Community Bot 1. Jonathon Reinhart Jonathon Reinhart 1 1 gold badge 3 3 silver badges 9 9 bronze badges. I've edited the title to something that I believe more clearly expresses the core of your question. Feel free to revert if I've misinterpreted it. Ixrec That is better, thank you. After writing up the whole question, I ran out of mental capacity to come up with a good title.
Add a comment. Active Oldest Votes. Improve this answer. Idan Arye Idan Arye I forgot to mention that the library claims to follow the Linux Coding Style , which happens to be what I follow as well. In there, you'll see that typedefing structures just to avoid writing struct is expressly discouraged. JonathonReinhart he's typedefing the pointer to struct not the struct itself. JonathonReinhart and actually reading that link I see that for "totally opaque objects" it is allowed.
0コメント