Is 'handle' synonymous to pointer in WinAPI? - windows

I've been reading some books on windows programming in C++ lately, and I have had some confusing understanding of some of the recurring concepts in WinAPI. For example, there are tons of data types that start with the handle keyword'H', are these supposed to be used like pointers? But then there are other data types that start with the pointer keyword 'P'. So I guess not. Then what is it exactly? And why were pointers to some data types given separate data types in the first place? For example, PCHAR could have easily designed to be CHAR*?

Handles used to be pointers in early versions of Windows but are not anymore. Think of them as a "cookie", a unique value that allows Windows to find back a resource that was allocated earlier. Like CreateFile() returns a new handle, you later use it in SetFilePointer() and ReadFile() to read data from that same file. And CloseHandle() to clean up the internal data structure, closing the file as well. Which is the general pattern, one api function to create the resource, one or more to use it and one to destroy it.
Yes, the types that start with P are pointer types. And yes, they are superfluous, it works just as well if you use the * yourself. Not actually sure why C programmers like to declare them, I personally think it reduces code readability and I always avoid them. But do note the compound types, like LPCWSTR, a "long pointer to a constant wide string". The L doesn't mean anything anymore, that dates back to the 16-bit version of Windows. But pointer, const and wide are important. I do use that typedef, not doing so will risk future portability problems. Which is the core reason these typedefs exist.

A handle is the same as a pointer only so far as both ID a particular item. Obviously a pointer is the address of the item so if you know it's structure you can start getting fields in the item. A handle may or may not be a pointer - basically if it is a pointer you don't know what it is pointing to so you can't get into the fields.
Best way to think of a handle is that it is a unique ID for something in the system. When you pass it to something in the system the system will know what to cast it to (if it is a pointer) or how to treat it (if it is just some id or index).

Related

Explain/Give example of "Hide pointer operations" in Code Complete 2

I am reading Code Complete 2, Chapter 7.1 and I don't understand the point author said below.
7.1 Valid Reasons to Create a Routine
Hide pointer operations
Pointer operations tend to be hard to read and error prone. By isolating them in routines (or a class, if appropriate), you can concentrate on the intent of the operation rather than the mechanics of pointer manipulation. Also, if the operations are done in only one place, you can be more certain that the code is correct. If you find a better data type than pointers, you can change the program without traumatizing the routines that would have used the pointers.
Please explain or give example of this purpose.
Essentially, the advice is a specific example of the data-hiding. It boils down to this -
Stick to Object-oriented design and hide your data within objects.
In case of pointers, the norm is to NEVER expose pointers of "internal" data-structures as public members. Rather make them private and expose ONLY certain meaningful manipulations that are allowed to be performed on the pointers as public member functions.
Portable / Easy to maintain
The added advantage (as explained in the section quoted) is that any change in the internal data structures never forces the external API to be changed. Only the internal implementation of the publicly exposed member functions needs to be modified to handle any changes.
Code re-use / Easy to debug
Also pointer manipulations are now NOT copy/pasted and littered all around the code with no idea what exactly they do. They are now limited to the member functions which are written keeping in mind how exactly the internal data structures are being manipulated.
For example if we have a table of data which the user is allowed to add rows into,
Do NOT expose
pointers to the head/tail of table.
pointers to the individual elements.
Instead create a table object that exposes the functions
addNewRowTop(newData)
addNewRowBottom(newData)
addNewRow(position, newData)
To take this further, we implement addNewRowTop() and addNewRowBottom() by simply calling addNewRow() with the proper position - another internal variable of the table object.

Reusable Priority queue implementation in google go

How would one go about writing the code for a reusable priority queue in Google Go or is one expected to define the Less Push and Pop function everytime a priority queue implementation is needed?
The later case is what one has to do. As far as Go doesn't have generics, it's the only available option at the moment.
Haven't tried it, but maybe you could use reflection and struct tags, if your cases happened to fit certain restrictons. You would require that your heapable type be a struct with a tag like `pq:"Key"` on the field you use for ordering, and that that field type be < comparable. It's far less powerful than a Less method but it might meet your needs.
Sorry I have no example code for you. I don't think it wouldn be terribly hard, but it would take me some time. Left for an exercise.
I might try this technique if I had a situation where I needed to handle arbitrary structs and I could live with the simplistic key restriction. For a finite set of types though, I wouldn't do this. I would just do it by the book, implementing heap.Interface separately for each type. It's really not that much work nor that many lines of code.
There used to be vector types in the container/vector module of the standard library that implemented these methods, based on a resizable slice, and perfectly worked as the container to be used with the heap module. Unfortunately, they got rid of vector, which I never understood as it implemented a nice method-level abstraction over a slice variable. So now, every time I see someone using the heap module in Go, they have to basically re-implement part of vector -- writing Push, Pop, Length, etc. based on a slice variable.
I'm not sure I understand the question.
I've implemented a queue (and stack and ring) using interface{} as the stored type here:
https://github.com/iNamik/go_container
Using interface{} allows you to store any type you want - although it doesn't help you enforce types ala generics, it gets the job done.
I could see creating a priority queue without much hassle.
Am I missing something?
I'd be happy to add a priority queue container if you think you'd find it useful.

What differences are allowed between IDL of CORBA server and client?

What I think I know so far is that the CORBA specification as such doesn't allow any differences between the IDL the server program uses and the IDL the client program uses.
However, in practice, certain differences are bound to work (pretty) universally, because the underlying communication mechanism is very probably GIOP (at least IIOP) and some differences are bound to not be detectable via IIOP.
What I like to establish is which differences are allowed between the server and client IDL universally between arbitrary ORBs as long as GIOP/IIOP is used.
For example: So far I assume it works to:
Add any type/interface to the server IDL as long as the types the client IDL knows about aren't touched or any unknown new types sent back to the client.
Add a method to an existing interface on the server side -- the client should be able to continue call objects with this interface, even though his IDL doesn't list said method. (This seems to be answered with yes here.)
Add a member to the end of an enum, as long as the client never sees this new value.
Add a member to a union, as long as the client never sees this Union type with the discriminator set to the new value.
My aim is to get to something like a short list of stuff one can do in an existing IDL to extend "the server" with new stuff without having to recompile exiting clients with the modified IDL.
Yes, the server and client method set need not match completely as the methods are accessed by name (the operation field in GIOP message) and independently. In other words, GIOP call includes the method name as string, later the parameters are encoded as they are expected by this parameter. See the example of the CORBA tie and CORBA stub.
Yes, if you create and export a new interface, it is just a new interface. It can be bound to any name service independently from others, and clients unaware of this new interface just will not be able to use it. The will be able to use the known types bound to the same name service.
Yes, GIOP writes enums as unsigned longs, first value is always encoded as zeros, successive identifiers take ascending numeric values, in order of declaration from left to right. Hence it is perfectly safe to append new enum identifies but not to remove and not to reorder.
Read GIOP specification, helps a lot. It is also very good to look into the code, generated by IDL compiler, and how does it change when something is changed in the IDL.
Surely it is not a good practice to use mismatching IDLs just because of the lack of care as it is also easy to introduce incompatible changes. This makes any sense probably only in cases if you cannot longer reach and update the client as it has been released to the user.

ioctl payload type/size violation

What can a driver do defensively to protect against a user-space app that issues an ioctl call with a pointer whose pointee is of a type/size different from what the driver expects/specified as part of its interface.
For e.g. say IOCTL x expects a (struct foo *) but caller issues it with (unsigned long) ((struct bar *)&bar). Will copy_from_user blow up/compromise the system stability?
Maybe one way is to expect caller to have CAP_SYS_ADMIN and have the implicit trust but is there another/better way?
Thanks.
copy_to/from_user use void pointers, meaning they are ignorant of any data types you pass. And given your example, even if they were aware of the data type, you still cannot trust your user: He could simply cast to the type you want:
struct bar *x;
copy_to_kernel_aware_of_foo((struct foo*)x);
Expecting the caller to have any kinds of root privileges or capabilities also does not solve your problem - root can also make mistakes or be evil.
Things that can help a bit:
Only use copy_to/from_user to copy around untyped byte buffers. Don't rely on kernel and user space having the same notion of complex data structures.
If you only worry about data types being wrong by mistake, you might consider tagging your data structure so that it contains some magic values in between the 'real' data. This will not help you against the caller deliberately faking data, though.
In terms of an attack surface, the attacker will probably not attack you by passing a wrong data type, but instead provide wrong values. There's nothing to help you instead of proper validation of all data that is passed to you from user space. Never trust anything without checking!

In Windows, is a HANDLE an address in a process' VAS or an independent index into something else?

Simply put, if I were to call some API returning a handle, such as GetActiveWindow(), which would give me a handle of type HWND, what do I get back? Is it a unique address in the process' VAS, or a unique index into some OS structure? Or something else?
An opaque integer identifier that has no meaning or use outside the API calls it's designed to work with - IOW, there's no way of knowing most of the time, and most of the time you shouldn't care. :-)
Yes to all of the above. In other words, it varies (widely) by handle type. Some are addresses (often hashed), others are indexes into particular tables, etc.

Resources