sarneaud•

My personal favourite Microsoft API WTF is the MsoTriState enum that "Specifies a tri-state Boolean value" using five values, three of which are documented as "not supported", leaving just msoTrue and msoFalse.

177
Paradox•

I prefer EnumClaw

28
parabol443•
15
quzox_•

True, False and ThisValueDoesNotExist.

3
zerpa•

... with msoTrue having the value of -1 ...

11
jephthai•

In Forth, the canonical value for truth is -1. This is because it's a signed integer with all bits set to 1. It grows on you and makes more sense over time.

14
MorrisonLevi•

If you end up using true/false as a bitmask then it makes a lot of sense; I've done this when emulating vector instructions.

1
AyrA_ch•

Why am I not surprised that this is from Office?

5
ne0terical•

msoTrue, incidentally, is negative

2
ubercaesium•

Yeah, that's a good one.

1
killerstorm•

There's a lot of weird shit in Windows APIs.

The biggest WTF I had is Volume Shadow Copy API -- it allows one to work with file system snapshots, e.g. for backup software. It's COM based and is moderately complex. Certainly more verbose than one would expect, but it's understandable.

The actual problem is that VSC API for Windows XP and Windows 2003 are incompatible. The use slightly different interfaces with same names and GUIDs. This means that your program can only target XP, or 2003, but not both. If you built a program for XP, it will crash on Windows 2003.

The most ironic thing is that interface versioning is one of the major features of COM -- it allows an object to expose several different versions of interfaces, which can be chosen by a program dynamically. But apparently VSC team had no idea how COM works.

(IIRC we solved this by wrapping this API into a DLL and loading a DLL depending on OS version.)

103
Creshal•

But apparently [Microsoft] team had no idea how [Microsoft's software stack] works.

Seems to be a recurring pattern.

92
lelanthran•

But apparently [Microsoft] team had no idea how [Microsoft's software stack] works.

Seems to be a recurring pattern.

Could be worse. Ever seen the way they deal with unicode? Developers using tchar_t have no idea if the resulting compiled binary will support unicode or not.

You literally cannot tell unless you check the output from the preprocessor, because some header in some third-party library might have defined _UNICODE, or worse, might have conditionally undefined it (so you don't get a compiler diagnostic).

It's been ten years or more since code pages were irrelevant - find me one Windows "dev" on a unicode-aware app who doesn't use code-pages somewhere.

13
TheThiefMaster•

Pretty sure UE4 (and by extension, all UE4 games) compiles only in unicode mode. I don't think it contains any mention of code pages.

1
lelanthran•

Pretty sure UE4 (and by extension, all UE4 games) compiles only in unicode mode. I don't think it contains any mention of code pages.

I'm not familiar with UE4, but if it doesn't mention code pages then maybe it's relying on whatever default code-page is set in Windows at execution?

As far as I can tell from this page over here:

On Windows, it will attempt to convert the text to UTF-16 using the default Windows MBCS encoding (eg Windows-1252 for US English and Western Europe, CP949 for Korean and CP932 for Japanese)

UE4 does in fact rely on a codepage (Windows-1252). Of course, there's no date on that page so I cannot tell if it is current or not. I assume it is.

So, if that page is current, developers using UE4 are coding a "unicode-aware" app that uses code-pages.

Even worse, they say that they do only unicode in the BMP, which means that they're basically doing only UCS-2, not UTF-16, hence developers using UE4 are actually using UCS-2 while being under the assumption that because strings internally are represented as UTF-16 they are unicode.

FWIW, if I was using a library that had the API all in UTF-16, I would assume that it was full UTF-16 all the way through, so you can't really blame the devs, especially as the MS API in this regards is so bad.

Windows provides a DBCS (Double-byte character set) API, MBCS (multibyte character set API) and wchar_t character set API, along with UTF-16 API functions. How is the developer supposed to know which is the correct one to use, and which of those depend on code-pages?

Read [this document] (http://utf8everywhere.org/) for why this is a problem and how to address it.

2
AyrA_ch•

IIRC we solved this by wrapping this API into a DLL and loading a DLL depending on OS version.

This is one of the times where .NET reflection shines. You can just dynamically compile any string into .NET code at runtime. I used this method a few times in the past to keep a software compatible with Windows XP.

4
the_isra17•

To be fair you can use dynamic dispatch with COM that could adapt the calls based on the system version. But it's probably simpler to use DLLs with clean code built from the interfaces.

9
alienus•

This is where .NET shines, since you are abstracted away from horribly designed low level window APIs. I genuinely believe .NET's main success lies in avoiding low level Windows API, so that code can be written sanely.

7
AyrA_ch•

occasionally using the Windows API has its benefits, for example for comparing byte arrays really fast.

The .NET framework is not as much an abstraction of the Windows API as it might seem at first. The Cryptography and System.Drawing namespaces are more or less just a wrapper for windows API, but the features to create a proper desktop shortcut or map a network drive are completely missing and you have to use COM again. On one side it would be beautiful if .NET provided a massively larger interface to the unmanaged API but on the other hand not implementing Windows specifics as much makes it more portable.

1
alienus•

I agree. I was abhorred to find that the System.Drawing namespace is so useless for you. That in fact may be an exception, though; since it actually makes things less clear when it comes to enumerations and stuff. Here's a good example:

PixelOffsetMode

Has the values:

  • Invalid
  • Default
  • HighSpeed
  • HighQuality
  • None
  • Half

But in actuality, only two things can happen: either there is half a pixel offset; the middle of a pixel is indicated by a pixel location, or its upper left corner.

.NET, even in documentation purports there are 6 different values, but in GDI we can clearly see that ultimately there are 2 actual different values, with the invalid and none representing the "I don't care, use the default" choice.

Additionally, I found that you cannot multithread drawing operations, even if you are using different images, you need a different process to do that, GDI won't let you do it because of a freaking global mutex. This is undocumented, and my attempts to multithread an image tiling application failed spectacularly, with many days of development time wasted.

2
pdp10•

using the Windows API has its benefits, for example for comparing byte arrays really fast.

memcmp is the C standard library, which I wouldn't think is the Windows API. I think of Win32 as the Windows API.

on the other hand not implementing Windows specifics as much makes it more portable.

I appreciate that Microsoft does apparently know how to create a spec that isn't implementation-defined, when they want to.

1
Yojihito•

I wonder why Microsoft just doesn't release new sane Windows APIs (without removing the old ones of course).

So instead of using the old, insane COM shit like the Volume Shadow Copy API you just use the Volue Shadow Copy API 2.

Sure, it will take years till the majority of the Windows software uses the new ones but one has to start somewhere.

1
Gotebe•
  1. They do; many parts of the system receive v2, v3 (e.g. Telephony API)

  2. Users have little to no incentive to rewrite old stuff => old APIs never stop being used; now M$ has several API versions and need to support them

6
ack_complete•

Similar crap has been going on with XAudio2 2.7/2.8/2.9, where they keep changing the interfaces while keeping the same name. The team seems to be under the strange impression that programmers target only one single Windows version at a time. At least in this case they've had the decency to change the interface IDs.

1
lurgi•

Two easy ways to make a bad API:

  • Make sure there are a lot of strange, possibly redundant, certainly inexplicable values you have to set
  • If you don't set absolutely everything right, have the function fail with a (this is important) generic error.
93
mayhempk1•

Also, if you are using a RESTful API, make sure you do not return HTTP status codes, you should return custom status codes with poorly written error messages or preferably no error messages.

46
AyrA_ch•

Nah, just return success code and no data

66
SimplySerenity•

My favorite is an API that returns "success" with no data sometimes, and then false with no data other times.

21
lelanthran•

I worked on a code base that #define the following:

#define TRUE      1
#define FALSE     0
#define SUCCESS   0
#define FAIL            1

And then we had great times looking at functions that returned both SUCCESS and FALSE, depending on what happened, then examining all the callers who were checking for TRUE and FAIL.

17
dardotardo•

I’ve seen a 200 OK success but error in the response body.

This one infuriates me.

6
AyrA_ch•

but error in the response body.

As long as it's otherwise identifiable it's ok. I've an API here that behaves like this. It only returns HTTP error codes for seriously messed up requests, but otherwise the response is always in the format of {success:bool,code:result_code,data:success_or_error_data,message:error_message}

1
lurgi•

-311: Invalid REST query

28
NoInkling•

I believe IIS uses custom "substatus codes", so you get response codes like 400.17.

8
alienus•

True, some explicitly indicate what is going wrong in IIS, like when no handler is configured for a certain URL/MIME type. Particularly useful for 500-range (internal server error) problems.

3
pTymN•

GL_INVALID_OPERATION

13
Sirflankalot•

tbf, there is a better way of doing error handling in modern GL with glDebugMessageCallback. It is a callback, but it's not that hard to deal with b/c of the good docs. Not defending the GL api, but it's pretty okay for design by awkward committee.

2
Madsy9•

What's wrong with GL_INVALID_OPERATION or OpenGL error reporting in general?

1
aumfer•

GL_INVALID_OPERATION

It would just be easier if it told you more. That error doesn't really give you enough info to know if OpenGL isn't in the proper state to call that function, or if one of your parameters is invalid, or if all of your parameters are valid but not in combination with each other.

The spec and documentation are pretty solid though, so its not too bad.

6
josefx•

Most implementations provide the KHR_debug extension, so you can get log messages with some contextual information with just a callback and a context creation flag.

2
jonhanson•

The most common way I've seen is trying to shoe-horn multiple APIs into one. Typically the result is a high number of parameters, where the meaning and optionality of many depend on the value of other parameters. E.g. "if Action is 5 or 6 then the Target parameter contains the filename, and the RetryCount paremeter isn't used (unless Action = 6)".

7
Wein•

Just write your code in Prolog and use the inference engine to determine how to call the API. Problem solved.

7
Tommah•

No.

1
thinsteel•

Or you could just hire Rasmus Lerdorf to make it for you.

1
0x5345414E•

Now just think about what the implementation must look like...

68
TheHobo•

ETW is definitely a nightmare, but in terms of comedy, I always liked [PathMakePretty](https://msdn.microsoft.com/en-us/library/windows/desktop/bb773725(v=vs.85\).aspx), and how it will have to live on forever for backcompat.

46
AyrA_ch•

This function only operates on paths that are entirely uppercase. For example: C:\WINDOWS will be converted to c:\windows, but c:\Windows will not be changed.

This is interesting though because under DOS you would usually only have uppercase file names and directories. But the function leaves properly cased names alone.

13
mayhempk1•

Nope. I've seen worse at work created by offshore devs.

35
juvee•

Triggered

11
Dockirby•

What if Customers have 4 different identifiers, but all APIs to work with customers can only take 1 of the 4, arbitrary chosen, and we at most return 2 of the identifiers in any one responses? And what if one of the the identifiers changes every day after the server restarts, and another represent an external ID that can come from another system (But if the External ID isn't set, we can just accept the main ID as the External ID. But only if there is no External ID)

That's a sufficient API, right? All the Jira stories got though QA, each one has a 1 sample payload. No sample responses were provided, but it passed QA so it must work.

3
JackTheSqueaker•

muratori = instant upvote

23
TOASTBOMB•

I c muratori, I upvote.

7†
parabol443•

Yeah, same with getting the monitor size on Windows. There is a documented way of using GetDeviceCaps - however, in traditional Microsoft fashion, it doesn't work reliably. It can return values that don't make sense at all. See this blog post.

The only reliable way to know how big the physical monitor is in millimeter on Windows is by parsing the device ID of the monitor, using that to filter all devices to get the windows registry key that you need in order to read the EDID data from the windows registry, then getting the dimensions from the EDID data.

The "rationale" if I understand it was that Microsoft didn't want apps to rely on a physical DPI of the monitor, rather their "logical" DPI, which may be user-adjusted. So they (intentionally?) didn't document that GetDeviceCaps may return wrong results because of their logical DPI bullshit and now nobody knows if the function actually works correctly 100% of the time. The stars say that the fixed it in Windows 8.1 and above, but I am not sure about that at all. So this is why you have to build a Rube-Goldberg machine, just to get the dimensions of a monitor.

The MSDN answers are hilarious, they are basically all just "why would you ever want the physical dimensions of the monitor?". Yeah, people don't actually want accurate scaling for CAD apps and I've never seen someone put a ruler to a screen and then blaming the developer for an inaccurate result. Never. /sarcasm

On the other hand, wayland or X11 directly give you the monitor size and off you go, like "hey I have this monitor ID, can I get the physical size, please? Here you go."

But in Microsofts defense, iOS is even more retarded, as the physical screen size has to be guessed from the Apple product name / screen dimensions. Because Apple only ever makes 5 devices that run iOS, so "why should we implement a function to ask for the device size? Just update all your code once a new iPhone comes out". Yay.

20
m50d•

The "rationale" if I understand it was that Microsoft didn't want apps to rely on a physical DPI of the monitor, rather their "logical" DPI, which may be user-adjusted. So they (intentionally?) didn't document that GetDeviceCaps may return wrong results because of their logical DPI bullshit and now nobody knows if the function actually works correctly 100% of the time. The stars say that the fixed it in Windows 8.1 and above, but I am not sure about that at all. So this is why you have to build a Rube-Goldberg machine, just to get the dimensions of a monitor.

As someone who used to use a weirdly sized monitor with a custom DPI setting, MS got it right there: finding the physical size should require a bunch of horrible hacks so that you use the logical size where possible. If I'm using a 2m wide projection screen that doesn't mean I want my UI elements to be physically 10mm high on it, thanks very much.

7
parabol443•

But if you want a projection of Napoleon on a video wall and you want to show how tall he is, you don't want the DPI to interfere with that (for example). Yes, UI shouldn't be laid out in millimeter, but the DPI is already exposed in several other APIs. There's no need for the DPI to interfere with the physical size of the monitor, it's ridiculous to imagine that the DPI can shrink or enlarge the physical size of a monitor. Otherwise, I'd get rich by just buying a 21" monitor, setting the DPI to 400% and then sell it as a 42" TV.

It's not Microsofts task to tell me how to develop my app. They could have just written "hey, if you want to scale UI elements, don't use the monitor size for that, use the DPI". It's the completely wrong place in the API to expose that.

And no, I don't think that requiring hacks to get the monitor size makes apps any better. macOS also has this "ask for the monitor size and you shall receive" API. But you don't see any apps on macOS using that for scaling UI elements, do you?

7
meneldal2•

I think it was well intended, they just didn't think of all the cases where it would be important.

5
Shimmen•

Regarding iOS:

[[UIScreen mainScreen] nativeBounds]

And

[[UIScreen mainScreen] nativeScale]

Sure, these are iOS 8.0 and forward but we've always had bounds and scale available. From those it's very easy to parse the screen pixel size.

2
Llebac•

Now that is some good nightmare fuel.

17
I_SUMMON_ANGELS•

How does this compare to Linux?

15
valarauca8•

Linux doesn't have event tracing.

Linux has a Packet Filter that over the course of 30 years became a fully featured JIT'd Packet Filter. That started to be used for Sandboxing processes, then tracing said processes, then tracing the kernel + processes.

But to answer your question the API is actually super nice. You collect the event from a userland socket in /proc, which you either mmap into a ring buffer to share memory with the kernel, or just read like a socket. The set up is pass a pointer to a null terminated utf8 path to a system call.


Linux is weird.

41
[deleted]•

[deleted]

1
Valmar33•

Linux doesn't have event tracing.

???

https://www.kernel.org/doc/Documentation/trace/events.txt

1
valarauca8•

I'm trying to make a joke based on truth.

FTrace is in kernel only. It also uses kprobes (generally) so it can have a non-trivial runtime costs. It is single user (root), and isn't dynamic. You can't switch it on/off, or run multiple traces for different purposes at different times.

EBPF is the most directly comparable to DTrace since it crosses user/kernel boundary pretty transparently (in most cases). And allows for you to write the actual logic of your tracing program in C99(ish).

3
defnotthrown•

There's no unified event tracing for the drivers, kernel and the userland in Linux as far as I know.

I know that dtrace came to linux but I'm not sure it's comparable.

I think WPA, MXA and PIX excell at correlating data from all kinds of systems, software and hardware. Not sure you can do something like that on linux without some scripting effort

21
jgalar•

LTTng (which I work on) is probably the closest you can get. It allows the correlation of userspace and kernel events on linux.

It is used by the linux port of .NET CoreCLR to provide an equivalent of Event Tracing on Windows.

14
AngusMcBurger•

Strangely, this time we don’t have to copy it to the end of the structure. Why? Who knows! Variety is the spice of life, I am told. Microsoft wants your life to be spicy.

Okay new favourite quote

10
delight1982•

Kafkaesque!

9
_argoplix•

I was working with a Kafka installation and trying to get anything done involved layers of bureaucracy, constantly changing rules, and lack of documentation about the previous 2 items. I felt like I had to follow a special Prozess to get anything done.

2
4655434b594f55•

I expected salesforce :)

7
Yojihito•
5
sapper123OP•

That's odd. I searched for the article using reddit's search and couldn't find it posted before. Guess I should use a better search engine next time.

1
Yojihito•

Reddit search is shit. I just googled "worst api ever made".

1
_argoplix•

They should put a SOAP interface on top of it.

3
Blakkhein•

What about WinApi, MFC and such?

2
armornick•

Most parts of the Windows API and MFC are actually pretty straightforward. It's just really low-level and carries a lot of backward compatibility baggage. Maybe if you'd start from scratch you could make a better API, but any API that has literally decades of backward compatibility is going to be a bit iffy.

2
trin123•

Yes, that’s right, every user of the Event Tracing for Windows API has to do the arithmetic and layout of the packed structure format themselves. I have absolutely no idea why the name has to be bundled in this way

They probably just take the entire struct and copy it into kernel space. And then they did not want to adjust the pointers or something

2
penismightier3•

And now because one developer didn't want to do this tedious work, he has forced every user to do tedious work, yay.

But yeah, might be the reason why.

2
DeathByTensors•

Yikes. Straight out of How to Write Unmaintainable Code. (For anyone who isn't familiar: https://www.se.rit.edu/~tabeec/RIT_441/Resources_files/How%20To%20Write%20Unmaintainable%20Code.pdf)

2
[deleted]•

[deleted]

1
tonefart•

Ebay's api... horrid piece of crap. Trading api cannot work with Seller/Inventory api... you have to reupload/re-insert every item. That and the mandatory browser login for OAuth2 with the new seller api.

1